This page covers adding client side APIs that cover wishlist functionalities such as adding or removing a product to wishlist, implementing a wishlist page, etc.

📘

Code Overview:

callGenrateRegidAPI(): Function that calls the generate-regid API. . This API generates a unique Swym Registration ID for a user.

callValidateSyncRegidAPI(): Function that calls the guest-validate-sync API. This API updates a guest regid when a user signs up or logs into your store.

AddToWishlist()/RemoveFromWishlist(): Wrapper Functions that calls the update-ctx API. This API handles adding or removing a product from Wishlist. These functions can be relied on when you don't want to use multiple wishlists.

fetchList(): Function that calls the fetch-lists API. This API fetches all list names a user has.

updateList(): Function that also calls the update-ctx API. This API handles adding adding, deleting or updating a product to a specific list.

createList(): This function calls the create API. This API handles creating a list with a specific list name.

fetchSwymAccessToken(): This function fetches the access token from headers when a user logs in.

getWishlistSocialCount(): This function calls the social-count API. This API fetches the social count of a product. (The number of times the product has been wishlisted)

Paste the below file onto your code files

import {
  setSwymLocalStorage,
  getSwymLocalStorage,
  updateLocalStorageRegid,
} from '../Utils/Utils';
import {v4 as uuidv4} from 'uuid';
import axios from 'axios';
import SWYM_CONFIG from '../swym.config';
const SWYM_PID = SWYM_CONFIG.PID;
/*
  @author: swym
  @notice: to get unique token as user identifier for swym
  @dev:    token call regid will be used for all swym api. genrated data will be stored in localstorage
  @param:  appId = Wishlist 
  @param:  useragenttype = mobile/desktop
*/
export const callGenrateRegidAPI = async ({
  appId = 'Wishlist',
  useragenttype = 'mobile',
  cb = () => {},
}) => {
  const myHeaders = new Headers();
  myHeaders.append('Content-Type', 'application/x-www-form-urlencoded');
  const urlencoded = new URLSearchParams();

  urlencoded.append('appId', appId);
  urlencoded.append('useragenttype', useragenttype);
  return await axios
    .post('/api/genrateRegid/', {
      appId,
      useragenttype,
    })
    .then((responseJSON) => {
      setSwymLocalStorage({
        regid: responseJSON?.data?.regid,
        sessionid: responseJSON?.data?.sessionid,
      });

      return responseJSON;
    })
    .then((res) => {
      if (!res.error) {
        cb();
      }
    })
    .catch((e) => {
      console.error('Exception', e);
      return {
        error: e.toString(),
      };
    });
};

/*
  @author: swym
  @notice: to generate new  regid and sync old regid user actions after login
  @dev:    update regid after user login and sync all previous wishlist actions to it
  @param:  regid = regid created before user login
*/

export const callValidateSyncRegidAPI = ({
  regid,
  appId = 'Wishlist',
  useragenttype = 'mobile',
  cb = () => {},
}) => {
  try {
    axios
      .post(`/api/validateSyncRegid/`, {
        appId,
        regid,
      })
      .then((responseJSON) => {
        updateLocalStorageRegid(responseJSON?.data?.regid);

        cb();
      });
  } catch (error) {
    return {
      error: error.toString(),
    };
  }
};

export const AddToWishlist = async (
  productId,
  variantId,
  productUrl,
  customLid,
) => {
  let lid = '';
  const swymConfig = getSwymLocalStorage();
  if (!swymConfig || !swymConfig.regid) {
    await callGenrateRegidAPI({
      username: null,
      uuid: uuidv4(),
      cb: () => AddToWishlist(productId, variantId, productUrl),
    });
  } else if (customLid) {
    try{
      return updateList(productId, variantId, productUrl, customLid)
      .then((response) => {
        return response;
      })
      .catch((e) => console.error(e));
    }catch(e){
      console.error('error update list', e);
    }
  } else {
    const res = fetchList().then((response) => {
      if (response) {
        if (response.length === 0) {
          const resp = createList()
            .then((response) => {
              if (response) {
                lid = response.lid;
                const resValue = updateList(
                  productId,
                  variantId,
                  productUrl,
                  lid,
                )
                  .then((response) => {
                    return response;
                  })
                  .catch((e) => console.error(e));
                return resValue;
              }
            })
            .catch((e) => console.error(e));
          return resp;
        } else {
          lid = lid === '' ? response[0].lid : lid;
          updateList(productId, variantId, productUrl, lid).then((response) => {
            return response;
          });
        }
        return response;
      }
    });
    return res;
  }
};

/*
  @notice: to remove product from wishlisted items
  @dev:    delete product from swym wishlisted products
  @author: swym
*/
export const removeFromWishlist = async (
  productId,
  variantId,
  productUrl, listId) => {
  var myHeaders = new Headers();
  myHeaders.append('Content-Type', 'application/x-www-form-urlencoded');

  const swymConfig = getSwymLocalStorage();

  var urlencoded = new URLSearchParams();
  urlencoded.append('regid', swymConfig.regid);
  urlencoded.append('sessionid', swymConfig.sessionid);
  urlencoded.append('lid', listId);
  urlencoded.append(
    'd',
    `[{ "epi":${variantId}, "empi": ${productId}, "du":"${productUrl}"}]`,
  );

  var requestOptions = {
    method: 'POST',
    headers: myHeaders,
    body: urlencoded,
    redirect: 'follow',
  };
  return fetch(
    `${SWYM_CONFIG.ENDPOINT}api/v3/lists/update-ctx?pid=${encodeURIComponent(
      SWYM_PID,
    )}`,
    requestOptions,
  )
    .then((response) => response.json())
    .then((result) => {
      return result;
    })
    .catch((error) => {
      console.error('error', error);

      return error;
    });
};

/*
  @author: swym
  @notice: fetch wishlist names created by clients
  @dev:    lists created by user - call only when user multilist is enable
  @return: array of created lists
*/

export const fetchList = async () => {
  var myHeaders = new Headers();
  myHeaders.append('Content-Type', 'application/x-www-form-urlencoded');
  const swymConfig = getSwymLocalStorage();
  if (!swymConfig || !swymConfig.regid) {
    await callGenrateRegidAPI({
      username: null,
      uuid: uuidv4(),
      cb: () => fetchList(),
    });
  } else {
    var urlencoded = new URLSearchParams();
    urlencoded.append('regid', swymConfig.regid);
    urlencoded.append('sessionid', swymConfig.sessionid);
    var requestOptions = {
      method: 'POST',
      headers: myHeaders,
      body: urlencoded,
      redirect: 'follow',
    };
    return await fetch(
      `${SWYM_CONFIG.ENDPOINT}api/v3/lists/fetch-lists?pid=${encodeURIComponent(
        SWYM_PID,
      )}`,
      requestOptions,
    )
      .then((response) => response.json())
      .then((result) => {
        return result;
      })
      .catch((error) => {
        console.error('error', error);

        return error;
      });
  }
};

/*
  @author: swym
  @notice: fetch content of given list 
  @dev:    use listid to fetch list content
  @params: lid - id of list
  @return: array of list items
*/
export const fetchListWithContents = async (lid) => {
  var myHeaders = new Headers();
  myHeaders.append('Content-Type', 'application/x-www-form-urlencoded');
  const swymConfig = getSwymLocalStorage();
  if (!swymConfig || !swymConfig.regid) {
    await callGenrateRegidAPI({
      username: null,
      uuid: uuidv4(),
      cb: () => fetchListWithContents(lid),
    });
  } else {
    var urlencoded = new URLSearchParams();
    urlencoded.append('regid', swymConfig.regid);
    urlencoded.append('sessionid', swymConfig.sessionid);
    // urlencoded.append('pid', SWYM_PID);
    urlencoded.append('lid', lid);

    var requestOptions = {
      method: 'POST',
      headers: myHeaders,
      body: urlencoded,
      redirect: 'follow',
    };
    return await fetch(
      `${
        SWYM_CONFIG.ENDPOINT
      }api/v3/lists/fetch-list-with-contents?pid=${encodeURIComponent(
        SWYM_PID,
      )}`,
      requestOptions,
    )
      .then((response) => response.json())
      .then((result) => {
        return result;
      })
      .catch((error) => {
        console.error('error', error);

        return error;
      });
  }
};

/*
  @author:  swym
  @notice:  add product to wishlist
  @dev:     use prodcutId and variantId to wishlist product 
  @params:  productId - product numbered id 
  @params:  variantId - product variant numbered id 
  @params:  productUrl - pdp page url 
  @params:  lid - list id to add product to 

  Note: Line 311 has 'a', which stands for adding a product. This API can also be used
  to remove a product by simply using 'd' and update product properties by using 'u'.
*/
export const updateList = async (productId, variantId, productUrl, lid) => {
  var myHeaders = new Headers();
  myHeaders.append('Content-Type', 'application/x-www-form-urlencoded');

  const swymConfig = getSwymLocalStorage();

  var urlencoded = new URLSearchParams();
  urlencoded.append('regid', swymConfig.regid);
  urlencoded.append('sessionid', swymConfig.sessionid);
  urlencoded.append('lid', lid);
  urlencoded.append(
    'a',
    `[{ "epi":${variantId}, "empi": ${productId}, "du":"${productUrl}", "cprops": {"ou":"${productUrl}"}, "note": null, "qty": 1 }]`,
  );

  var requestOptions = {
    method: 'POST',
    headers: myHeaders,
    body: urlencoded,
    redirect: 'follow',
  };
  return await fetch(
    `${SWYM_CONFIG.ENDPOINT}api/v3/lists/update-ctx?pid=${encodeURIComponent(
      SWYM_PID,
    )}`,
    requestOptions,
  )
    .then((response) => response.json())
    .then((result) => {
      return result;
    })
    .catch((error) => {
      console.error('error', error);

      return error;
    });
};

/*
  @author: swym
  @notice: create new list by name
  @dev:    for multiple list. this create new list for given listname
  @params: listName - name of new list (>3 char && unique)
*/
export const createList = async (listName) => {
  var myHeaders = new Headers();
  myHeaders.append('Content-Type', 'application/x-www-form-urlencoded');

  const swymConfig = getSwymLocalStorage();
  if (!swymConfig || !swymConfig.regid) {
    await callGenrateRegidAPI({
      username: null,
      uuid: uuidv4(),
      cb: () => createList(listName),
    });
  } else {
    var urlencoded = new URLSearchParams();
    urlencoded.append('lname', listName || 'My Wishlist');
    urlencoded.append('regid', swymConfig.regid);
    urlencoded.append('sessionid', swymConfig.sessionid);

    var requestOptions = {
      method: 'POST',
      headers: myHeaders,
      body: urlencoded,
      redirect: 'follow',
    };
    return await fetch(
      `${SWYM_CONFIG.ENDPOINT}api/v3/lists/create?pid=${encodeURIComponent(
        SWYM_PID,
      )}`,
      requestOptions,
    )
      .then((response) => response.json())
      .then((result) => {
        return result;
      })
      .catch((error) => {
        console.error('error', error);

        return error;
      });
  }
};

/*
  @author: swym
  @notice: - 
  @dev:    fetches the access token from headers when a user logs in
*/

export const fetchSwymAccessToken = async () => {
  const res = await axios
    .post('/api/getCustomerAccessToken')
    .then((response) => {
      return response.data;
    })
    .catch((e) => {
      console.error('Exception', e);
      return e;
    });
  return res;
};

/**
 * @author swym
 * @dev fetches the wishlist social count of a product
 * @param {Number} empi - product id of the product
 * @param {Boolean} skipCache - should getting data from cache be skipped 
 * @returns {Object} data - { count, empi }
 */
export const getWishlistSocialCount = async ({empi}, skipCache = false) => {
  try {
    let localCahce = getSwymLocalStorage();
    let cachedProducts = localCahce.products;
    let currProductIdx =
      cachedProducts &&
      cachedProducts.findIndex((product) => product.empi == empi);
    let productInfo = cachedProducts && cachedProducts[currProductIdx];

    if (!skipCache && productInfo) {
      return {
        data: productInfo,
      };
    }

    if (!localCahce || !localCahce.regid) {
      await callGenrateRegidAPI({});
    }
    localCahce = getSwymLocalStorage();
    var myHeaders = new Headers();
    myHeaders.append('Content-Type', 'application/x-www-form-urlencoded');
    var queryParams = new URLSearchParams();
    queryParams.append('pid', SWYM_PID);
    
    var urlencoded = new URLSearchParams();
    urlencoded.append('empi',empi);
    urlencoded.append('regid', localCahce.regid);
    urlencoded.append('sessionid', localCahce.sessionid);

    var requestOptions = {
      method: 'POST',
      headers: myHeaders,
      body: urlencoded,
      redirect: 'follow',
    };

    const response = await fetch(
      `${SWYM_CONFIG.ENDPOINT}api/v3/product/wishlist/social-count?${queryParams}`,
      requestOptions
    );
    const responseData = await response.json();

    //
    if (responseData?.data?.count) {
      const newCount = responseData.data.count;

      if (cachedProducts) {
        if (productInfo) {
          localCahce.products[currProductIdx].count = newCount;
          setSwymLocalStorage(localCahce);
        } else {
          if(cachedProducts.length === 20)
            cachedProducts.shift();
          cachedProducts.push(responseData.data);
          setSwymLocalStorage({
            ...localCahce,
            products: cachedProducts,
          });
        }
      } else {
        setSwymLocalStorage({
          ...localCahce,
          products: [responseData.data],
        });
      }
    }
    return responseData;
  } catch (error) {
    console.error(error);
  }
};