Search code examples
javascriptnode.jsstronglooploopback

Implement Callbacks in Loopback 'Before Save' hook


Good day! I am pretty new to Node.js and Loopback. The below is driving me crazy.

I want to write attribute values to my model instance on "before save". I get one value from the calling REST call:

ctx.instance.hash

Then, I need to call a REST API, get the response, and write the value into the model. Getting the value from the API call works, but I get the value from another function.

But I can't get the value back into the original function's scope, to do the following:

tx.instance.somedata = externalData;

I have tried: 1. Making this a global var, but in the original calling function, the value just remains "undef". 2. Doing a "Return" on the value

Both to no avail - the value remains "undefined"

I was thinking that the variable never gets populated, and I need to use callbacks, but I am not sure how to implement the callback function in this case.

Any pointers or assistance will be greatly appreciated, thanks!

module.exports = function(Blockanchor) {

  Blockanchor.observe('before save', function GetHash(ctx, next) {
    if (ctx.instance) {
      //console.log('ctx.instance', ctx.instance)
      var theHash = ctx.instance.hash; //NB - This variable is required for the external API call to get the relevant data

      //Run below functions to call an external API
      //Invoke function
      ExternalFunction(theHash);
      //See comment in external function, I do not know how to get that external variable here, to do the following:
      ctx.instance.somedata = externalData;

    } 
    next();
  }); //Blockanchor.observe

}//module.exports = function(Blockanchor)

Function ExternalFunction(theHash){
  //I successfully get the data from the external API call into the var "externalData"
  var externalData = 'Foo'
  //THIS IS MY PROBLEM, how do I get this value of variable  "externalData" back into the code block above where I called the external function, as I wish to add it to a field before the save occurs
 }

Solution

  • You should implement a promise in your external function, then wait for the external API call and return the response using the resolve callback.

    module.exports = function(Blockanchor) {
    
      Blockanchor.observe('before save', function GetHash(ctx, next) {
        if (ctx.instance) {
          //console.log('ctx.instance', ctx.instance)
          var theHash = ctx.instance.hash; //NB - This variable is required for the external API call to get the relevant data
    
          //Run below functions to call an external API
          //Invoke function
          ExternalFunction(theHash).then(function(externalData){
            ctx.instance.somedata = externalData;
    
            next();
          })
        } else {
            next();
        }
      }); //Blockanchor.observe
    
    }//module.exports = function(Blockanchor)
    
    function ExternalFunction(theHash){
        return new Promise(function(resolve, reject){
            var externalData = 'Foo'
            resolve(externalData)
        })
     }