bukubapi
bukubapi

Reputation: 537

Issue with Callback - OpenWhisk with Nodejs runtime

I am developing a module in BlueMix OpenWHisk, where after a Cloudant feed change, I need to call an url, which would update few details on another platform. I am using nodejs runtime.

The ask is for my action to wait, for the result of the POST request, to the url mentioned above. If the POST was successful, then I should execute the next sequence of events.

Questions:

  1. How to wait for the result of the POST request, before the next sequence is executed ?

  2. Is it possible to wait and return the result of POST request.

Positing my code

   /**
  *
  * main() will be invoked when you Run This Action
  *
  * @param OpenWhisk actions accept a single parameter, which must be a JSON object.
  *
  * @return The output of this action, which must be a JSON object.
  *
  */

const util = require('util');
var http = require('http');

function main(params) {

    // Updated the status of the User
    params.status ="updated1";

    var options = {
                host: "myhost.mybluemix.net",
                path: "/addtoimc",
                method: "POST",
                headers: {
                    "Content-Type": "text/plain"
                }
            };


      return {message : addtoIMC(options)};

}

function createRequest(data, options)
{

    return http.request(options, function (res) {
            var responseString = "";

            res.on("data", function (data) {
                responseString += data;
                // save all the data from response
            });
            res.on("end", function () {
                console.log("AAA" + responseString); 
            });
        });
}



function addtoIMC(options)
{
    return new Promise(function(resolve, reject) {
            var req = createRequest("Hello",options);
            var reqBody = "post_data";
            req.write(reqBody);
            req.end();

        });
}

Upvotes: 2

Views: 349

Answers (2)

Gaurang Deshpande
Gaurang Deshpande

Reputation: 232

You can write something like this:

function main(params) {
  const http = require('http');

  const inputVariable = params.inputVariableNameToBePassedToThisAction;

  const options = {
    host: "myhost.mybluemix.net",
    path: "/addtoimc",
    method: "POST",
    headers: {
      "Content-Type": "text/plain"
    }
  };

  const createRequest = (options) => {
    const promise = new Promise((resolve, reject) =>{
      http.request(options, function(err, resp) {
        if(err){
          reject(`401: ${err}`);
        }
        else{
          let responseString = "";

          res.on("data", function (data) {
            responseString += data;
            // save all the data from response
          });
          res.on("end", function () {
            console.log("AAA" + responseString);
          });
          resolve(responseString);
        }
      });
    });
    return promise;
  };

  return createRequest(options)
    .then(data => {
      //process data from POST request
      //call next methods if there are any, on positive response of POST request
      const outputVariable = data.someImportantParameterToExtract;
      const resp = {
        keyToUse : outputVariable
      };
      //
      return ({
        headers: {
          'Content-Type': 'application/json'
        },
        statusCode: 200,
        body: new Buffer(JSON.stringify(resp)).toString('base64')
      });
    })
    .catch(err => {
      //stop execution because there is some error
      return ({
        headers: {
          'Content-Type': 'application/json'
        },
        statusCode: 400,
        body: new Buffer(JSON.stringify(err)).toString('base64')
      });
    });
};

You can write first function, call it and use .then(data => {}).catch(err => {}) for positive and negative scenario respectively Give it a try...

Upvotes: 0

markusthoemmes
markusthoemmes

Reputation: 3120

Your request logic is a bit broken. For instance your promise is never resolved and you don't listen on the right callbacks.

I suggest you switch to use request-promise. The following should work

const request = require('request-promise');

function main(params) {
    return request({
        url: "http://myhost.mybluemix.net/addtoimc",
        method: "POST",
        headers: {
            "Content-Type": "text/plain"
        }
    }).then(response => {
        if(response.success) {
            return Promise.resolved({message: "nice"});
        } else {
            return Promise.rejected({error: "it broke"});
        }
    });
}

Upvotes: 6

Related Questions