Skip to content

Instantly share code, notes, and snippets.

@marshallswain
Last active June 16, 2022 18:29
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marshallswain/d800a56479546912370f4e24f21c7f67 to your computer and use it in GitHub Desktop.
Save marshallswain/d800a56479546912370f4e24f21c7f67 to your computer and use it in GitHub Desktop.
A Feathers hook to remap service.create to do an upsert
module.exports = function (upsertQuery) {
if (typeof upsertQuery !== 'function') {
console.warn('No `upsertQuery` function was passed to the mapCreateToUpsert hook. Please set params.upsertQuery in the hook context to dynamically declare the function.')
}
return function mapCreateToUpsert (context) {
const { service, data, params } = context // const data = { address: '123', identifier: 'my-identifier' }
upsertQuery = params.upsertQuery || upsertQuery
if (typeof upsertQuery !== 'function') {
throw new Error('you must pass a `upsertQuery` function to the mapCreateToUpsert hook in the options or as `params.upsertQuery` in the hook context')
}
params.mongoose = Object.assign({}, params.mongoose, { upsert: true })
params.query = upsertQuery(context) // { address: '123' }
return service.patch(null, data, params)
.then(result => {
context.result = result
return context
})
}
}
const mapCreateToUpsert = require('./hook.map-create-to-upsert')
app.service('my-service').hooks({
before: {
all: [],
find: [],
get: [],
create: [
mapCreateToUpsert(context => {
const { data } = context
return { address: data.address }
})
],
update: [],
patch: [],
remove: []
}
})
@compwright
Copy link

compwright commented Jan 13, 2018

The hook doesn't handle errors as expected if something goes wrong in upsertQuery(). This fixes the issues:

const logger = require('winston')

module.exports = function(upsertQuery) {
  if (typeof upsertQuery !== 'function') {
    logger.warn(
      'No `upsertQuery` function was passed to the mapCreateToUpsert hook. Please set params.upsertQuery in the hook context to dynamically declare the function.'
    )
  }

  return function upsert(context) {
    const { service, data, params } = context

    upsertQuery = params.upsertQuery || upsertQuery
    if (typeof upsertQuery !== 'function') {
      throw new Error(
        'You must pass a `upsertQuery` function to the mapCreateToUpsert hook in the options or as `params.upsertQuery` in the hook context'
      )
    }

    params.mongoose = Object.assign({}, params.mongoose, { upsert: true })
    
    try {
      params.query = upsertQuery(context)
    } catch (error) {
      context.error = error
      return context
    }

    return service
      .patch(null, data, params)
      .then(result => {
        delete context.error
        context.result = result
      })
      .catch(error => {
        context.error = error
      })
      .then(() => context)
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment