0

I am trying to get the value of a queried ID called from another class however when I call the function it gives me a promise chain and not the value I am looking for.

The method in the class 'Helper' is below

function querySF() {
  var conn = new jsforce.Connection({
    // you can change loginUrl to connect to sandbox or prerelease env.
    loginUrl: 'https://www.salesforce.com'
  });

  return conn.login('someusername', 'password')
    .then(function(userInfo) {
      // Now you can get the access token and instance URL information.
      // Save them to establish connection next time.
      console.log(conn.accessToken);
      console.log(conn.instanceUrl);
      // logged in user property
      console.log("User ID: " + userInfo.id);
      console.log("Org ID: " + userInfo.organizationId);
      // ...

      return conn.query("SELECT Id FROM some place Where name = 'some name'")
    })
    .then(function(result) {
      console.log("total : " + result.totalSize);
      console.log("fetched : " + result.records.length);
      // is returning the id
      console.log(result.records[0].Id);
      return result.records[0].Id; // can see the id here when debugging
    })
    .catch(function(err) {
      console.error(err);
    });
}

I am exporting the module like this at the bottom of the class:

exports.querySF = querySF();

The other class called 'BookingEvent' calls the method like this: var theId = Helper.querySF; and it returns a promise, I have printed the promise to console console.log(Helper.querySF); to see the results:

Promise {
  _45: 0,
  _81: 1,
  _65: 'a0L46111001LyvsEAC', // This is the value I need
  _54: null,
  then: [Function],
  stream: [Function: createRequest] }

It was thought that I should be able to just use

helpers.querySF().then(function(value){
  console.log(value);
}) 

and be able to get the value however I am getting this error:

Failed: helpers.querySF is not a function

I am quite new to promises and no one at my company can seem to solve the issue. I have research many different ways of resolving promises however they do not work and I also do not understand. Could someone help me resolve this promise so the id accessible whenever I call this method, which will be multiple times with different queries I will be sending in.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
Nicole Phillips
  • 753
  • 1
  • 18
  • 41

1 Answers1

0

If the promises are not related each other, you may find better Promise.all() here instead of chaining promises in this way. Then resolve all of them. If actually you get the name of the second query from the first promise, actually you need to chain them. Then you are missing a catch in order to catch errors for the first promise.

And maybe a refactor using function may help the code to look better.

return conn.login('someusername', 'password')
    .then(elaborateUserInfo)
    .catch(catchErrors)
    .then(elaborateResults)
    .catch(catchErrors);
    
function elaborateUserInfo(userInfo) {
  // Now you can get the access token and instance URL information.
      // Save them to establish connection next time.
      console.log(conn.accessToken);
      console.log(conn.instanceUrl);
      // logged in user property
      console.log("User ID: " + userInfo.id);
      console.log("Org ID: " + userInfo.organizationId);
      // ...

      return conn.query("SELECT Id FROM some place Where name = 'some name'");
}


function elaborateResults(result) {
  console.log("total : " + result.totalSize);
  console.log("fetched : " + result.records.length);
  // is returning the id
  console.log(result.records[0].Id);
  return result.records[0].Id; // can see the id here when debugging
}

function catchErrors(err) {
  console.log(err);
}

It looks better, doesn't it?

Instead, the only reason for this error Failed: helpers.querySF is not a function is that you don't have that method in your object. Are you sure you really exported it in order to be visible outside your module?

quirimmo
  • 9,800
  • 3
  • 30
  • 45
  • Is there away to make the conn.login and the elaborate user info function to be used throughout the application and remain static? What would be optimal is that the conn.login and user is logged in at the beginning of my automation so it is not constantly reestablishing the connection. – Nicole Phillips May 25 '17 at 14:03
  • Sure that you can. But I need few info before to provide you a good example. Which version of angular are you using? and do you want to bootstrap these operations directly at the beginning of your app so that you can keep them everywhere always, or do you want to init them just in some cases? – quirimmo May 25 '17 at 15:13
  • It would be init. I am using protractor to test my angular-js application so really I am only using javascript. Mainly I want to be able to establish the connect once at the load of the configuration file, this is basically the main for the protractor app, on prepare is located here. I would like it so the login can be changed at any time and the query to be in separate method. – Nicole Phillips May 25 '17 at 16:33
  • Sorry for the delay in the answer. OK but as you said, you have the onPrepare method and inside there you can define your operations, and then you can add a mock module in this way: `browser.addMockModule('login', myLoginFunction);` Did you try this? – quirimmo May 26 '17 at 13:24