Hello all i am trying to add endpoints to magento & use them into vsf
(to set wishlist on server instead on local storage)
Here is the magento module
1.Attached
-
Added extension to vue-storefront-api, to call magento service
register wishlist in VSF api config
“registeredExtensions”: [ -
added src/api/extensions/wishlist-api/index.js
`import { apiStatus } from '../../../lib/util';` `import { Router } from 'express';` `import catalog from '../../catalog';` `import bodybuilder from 'bodybuilder'const Magento2Client = require('magento2-rest-client').Magento2Client/** endpoint /api/ext/wishlist-api */` `module.exports = ({ config, db }) => { const client = Magento2Client(config.magento2.api)` ` client.addMethods('wishlist', function (restClient) {` ` return {` ` getProducts(customerId) {` ` return restClient.get(/wishlist/${customerId});` ` },` ` addProduct(customerId, productId) {` ` return restClient.post(/wishlist/${customerId}/${productId})` ` },` ` deleteProduct(customerId, productId) {` ` return restClient.delete(/wishlist/${customerId}/${productId})` ` }` ` }` ` }) const api = Router()` ` api.get('/:customerId', (req, res) => {` ` client.wishlist.getProducts(req.params.customerId)` ` .then(products => {` ` if (products.length) {` ` // need to return products in format VSF understands` ` return getProductsFromCatalog(products.map(x => x.product_id), req.query.storeCode)` ` } else {` ` return []` ` }` ` })` ` .then(result => {` ` apiStatus(res, result, 200)` ` })` ` .catch(err => {` ` apiStatus(res, err, 500);` ` })` ` }) api.post('/:customerId/:productId', (req, res) => {` ` client.wishlist.addProduct(req.params.customerId, req.params.productId)` ` .then(result => {` ` apiStatus(res, result, 200)` ` })` ` .catch(err => {` ` apiStatus(res, err, 500);` ` })` ` }) api.delete('/:customerId/:productId', (req, res) => {` ` client.wishlist.deleteProduct(req.params.customerId, req.params.productId)` ` .then(result => {` ` apiStatus(res, result, 200)` ` })` ` .catch(err => {` ` apiStatus(res, err, 500);` ` })` ` }) async function getProductsFromCatalog(ids, storeCode = 'default') {` ` const index = config.elasticsearch.indices.find(x=>x.match(new RegExp(_${storeCode}$))) || config.elasticsearch.indices[0]` ` try {` ` const resp = await queryCatalogRouteByProductId(ids, index)` ` if (resp.hits.hits.length) {` ` return resp.hits.hits` ` } else {` ` throw new Error(no products found in catalog ${index} for ids ${ids.join(', ')})` ` }` ` } catch (err) {` ` throw new Error(err)` ` }` ` } function queryCatalogRouteByProductId(ids, index) {` ` return new Promise((rsv, rjs) => {` ` const res = { json: rsv }` ` const req = {` ` method: 'POST',` ` query: {},` ` url: /${index}/product/_search` , ` body: bodybuilder()` ` .filter('terms', 'id', ids)` ` .build()` ` }` ` catalog({ config, db })(req, res)` ` })` ` } return api` `}`
-
Added business logic to vue-storefront, to call vue-storefront-api servicesadded enpoints in your VSF config
"wishlist": {
"pull_endpoint": "/api/ext/wishlist-api/{{customer_id}}",
"additem_endpoint": "/api/ext/wishlist-api/{{customer_id}}/{{product_id}}",
"deleteitem_endpoint": "/api/ext/wishlist-api/{{customer_id}}/{{product_id}}"
},
-
extended existing /core/modules/wishlist/store/actions.ts
to call the services if user is logged inimport Vue from 'vue'
import { ActionTree } from 'vuex'
import * as types from './mutation-types'
import i18n from '@Vue Storefront/i18n'
import { htmlDecode } from '@Vue Storefront/core/store/lib/filters'
import rootStore from '@Vue Storefront/core/store'
import RootState from '@Vue Storefront/core/types/RootState'
import WishlistState from '../types/WishlistState'
import { Logger } from '@Vue Storefront/core/lib/logger'
import { TaskQueue } from '@Vue Storefront/core/lib/sync'
import config from 'config'async function _serverLoad (customer_id: number) {
const url = config.wishlist.pull_endpoint.replace('{{customer_id}}', customer_id) return TaskQueue.execute({
url,
payload: {
method: 'GET',
headers: { 'Content-Type': 'application/json' },
mode: 'cors'
},
silent: true
})
.then(async task => {
if (task.resultCode === 200) {
// diffLog = await dispatch('merge', { serverItems: task.result, clientItems: getters.getCartItems, dryRun: dryRun, forceClientState: forceClientState })
return task.result.map(x => x._source)
} else {
throw new Error('error retrieving wishlist')
}
})
}async function _serverAddItem (customer_id: number, product_id: number) {
const url = config.wishlist.additem_endpoint.replace('{{customer_id}}', customer_id).replace('{{product_id}}', product_id) return TaskQueue.execute({
url,
payload: {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
mode: 'cors'
},
silent: true
})
.then(async task => {
if (task.resultCode === 200) {
// diffLog = await dispatch('merge', { serverItems: task.result, clientItems: getters.getCartItems, dryRun: dryRun, forceClientState: forceClientState })
return true
} else {
throw new Error('error adding item wishlist')
}
})
}async function _serverDeleteItem (customer_id: number, product_id: number) {
const url = config.wishlist.deleteitem_endpoint.replace('{{customer_id}}', customer_id).replace('{{product_id}}', product_id) return TaskQueue.execute({
url,
payload: {
method: 'DELETE',
headers: { 'Content-Type': 'application/json' },
mode: 'cors'
},
silent: true
})
.then(async task => {
if (task.resultCode === 200) {
// diffLog = await dispatch('merge', { serverItems: task.result, clientItems: getters.getCartItems, dryRun: dryRun, forceClientState: forceClientState })
return true
} else {
throw new Error('error deleting item wishlist')
}
})
}const actions: ActionTree<WishlistState, RootState> = {
clear (context) {
context.commit(types.WISH_LOAD_WISH, [])
},
async load ({ commit, getters, rootState, rootGetters }, force: boolean = false) {
if (!force && getters.isWishlistLoaded) return
commit(types.SET_WISHLIST_LOADED) Vue.prototype.$db.wishlistCollection.getItem('current-wishlist', (err, storedItems) => {
if (err) throw new Error(err)
commit(types.WISH_LOAD_WISH, storedItems)
Logger.info
('Wishlist state loaded from browser cache. ', 'cache', storedItems)()
})
if (rootGetters['user/isLoggedIn']) {
const storedItems = await _serverLoad(rootState.user.current.id)
commit(types.WISH_LOAD_WISH, storedItems)
Logger.info
('Wishlist state loaded from server. ', 'server', storedItems)()
}
},
async addItem ({ commit, rootGetters, rootState }, product) {
commit(types.WISH_ADD_ITEM, { product })
rootStore.dispatch('notification/spawnNotification', {
type: 'success',
message: i18n.t('Product {productName} has been added to wishlist!', { productName: htmlDecode(product.name) }),
action1: { label: i18n.t('OK') }
})
if (rootGetters['user/isLoggedIn']) {
await _serverAddItem(rootState.user.current.id, product.id)
Logger.info
('Wishlist product added to server. ', 'server', product)()
}
},
async removeItem ({ commit, rootGetters, rootState }, product) {
commit(types.WISH_DEL_ITEM, { product })
rootStore.dispatch('notification/spawnNotification', {
type: 'success',
message: i18n.t('Product {productName} has been removed from wishlit!', { productName: htmlDecode(product.name) }),
action1: { label: i18n.t('OK') }
})
if (rootGetters['user/isLoggedIn']) {
await _serverDeleteItem(rootState.user.current.id, product.id)
Logger.info
('Wishlist product deleted from server. ', 'server', product)()
}
}
}
export default actions
I am facing HTTP ERROR undefined" on api call on adding product to wishlistWhat you guys think , how we can fix this one ?