0

I have a http post request which returns ID. I then try to pass that ID into another function. However, inside the next function I have a timeout that will loop the function to check the status. The ID returns undefined each time inside the timeout function.

First Function

Here I have 'res' which is a result from another function. I grab the status ID from the returned json and send it to 'getAlbum'.

anotherFunction(res) {
  this.getAlbum(res);
}

GetAlbum

If I do a console log immediately inside this function, it correct emits the correct ID. However, if I do it inside the 'checkAblumStatus' function, the id part is undefined.

getAlbum(id){

 var statusID = id.status_id;

  console.log('id = ' + statusID) // returns id

  var statusIDRequest = 'url' + statusID;

  var checkAblumStatus = function (statusIDRequest) {

    console.log('statusIDRequest = ' + statusIDRequest) // returns undefined for the ID part

    this.http.get(statusIDRequest).subscribe(res => {
      if (res.status == "completed") {
        // completed
      } else if (res.status == "failed") {
        // failed
      } else {
        setTimeout(checkAblumStatus, 1000);
      }
    });
  };

  setTimeout(checkAblumStatus, 1000);
}

Any help here would be very grateful :)

Dexygen
  • 12,287
  • 13
  • 80
  • 147
  • Possible duplicate of [What's the meaning of "=>" (an arrow formed from equals & greater than) in JavaScript?](https://stackoverflow.com/questions/24900875/whats-the-meaning-of-an-arrow-formed-from-equals-greater-than-in-javas) – Oliver Mar 22 '18 at 09:07

3 Answers3

1

This happens because of the scope of your variables.

  var checkAblumStatus = function (statusIDRequest) {

    console.log('statusIDRequest = ' + statusIDRequest) // returns undefined for the ID part

    this.http.get(statusIDRequest).subscribe(res => {
      if (res.status == "completed") {
        // completed
      } else if (res.status == "failed") {
        // failed
      } else {
        setTimeout(checkAblumStatus, 1000);
      }
    });
  };

In the context of your function, this references the function itself, not your object.

You need to use a closure or a fat arrow like this.

  var checkAblumStatus = (statusIDRequest) => {

You also need to provide a avariable to your calls.

setTimeout(checkAblumStatus(variable), 1000);
  • Thanks for the response @trichetriche. I gave this a go. However the 'res.status' line errors out in typescript with '[ts] Property 'status' does not exist on type 'Object'. in using a fat arrow. –  Mar 22 '18 at 10:23
  • You mistyped your service function. Try with this `this.http.get(statusIDRequest).subscribe((res: any) => {`, or retype your service function. –  Mar 22 '18 at 10:25
  • Brilliant. I'm actually getting a result now. The only issue is now that when it hits the 'else' result, it's not looping back to test the function again. I tried your variable to setTimeOut and get 'Cannot invoke an expression whose type lacks a call signature. Type 'void' has no compatible call signatures.' –  Mar 22 '18 at 10:39
  • `setTimeout(() => checkAblumStatus(variable), 1000);` should work –  Mar 22 '18 at 10:40
  • Same thing I'm afraid. –  Mar 22 '18 at 10:49
  • Well then, take a look a **[this question](https://stackoverflow.com/questions/39691889/error-cannot-invoke-an-expression-whose-type-lacks-a-call-signature)**. You should type the return of your functions to avoid this kind of error. –  Mar 22 '18 at 10:51
  • Ah, I thought that's because we set 'res' to any. Anyway, I ended up just creating a separate time out function to call if the result didn't match 'completed'. Thanks for the help! :) –  Mar 22 '18 at 11:11
0

you can pass the id for the function as follow

function getAlbum(id){

 var statusID = id.status_id;

  console.log('id = ' + statusID) // returns id

  var statusIDRequest = 'url' + statusID;

  var checkAblumStatus = ((statusIDRequest) => {

    console.log('statusIDRequest = ' + statusIDRequest) // returns undefined for the ID part

    this.http.get(statusIDRequest).subscribe(res => {
      if (res.status == "completed") {
        // completed
      } else if (res.status == "failed") {
        // failed
      } else {
        setTimeout(checkAblumStatus, 1000);
      }
    });
  })(statusIDRequest);

  setTimeout(checkAblumStatus, 1000);
}
Raed Khalaf
  • 1,997
  • 2
  • 13
  • 29
  • Hi Raed, Thanks! I just gave this a go. It results in "ERROR TypeError: Cannot read property 'http' of undefined". Any ideas? –  Mar 22 '18 at 10:18
  • i edit the answer, just change the function to arrow function – Raed Khalaf Mar 22 '18 at 10:26
0

You get confused with variable and param name.

var statusIDRequest = 'url' + statusID;
       ^       ^   // this variable
 var checkAblumStatus = function (statusIDRequest) {
                                     ^     ^ // .. is not the same not this param

Change the name of the variable like this, so you don't get rid of the name:

getAlbum(id){

 var statusID = id.status_id;

  console.log('id = ' + statusID) // returns id

  var statusID = 'url' + statusID;

  var checkAblumStatus = function (statusIDRequest) {

    console.log('statusIDRequest = ' + statusIDRequest) // returns the ID part

    this.http.get(statusIDRequest).subscribe(res => {
      if (res.status == "completed") {
        // completed
      } else if (res.status == "failed") {
        // failed
      } else {
        setTimeout( () => checkAblumStatus (statusIDRequest), 1000);
      }
    });
  };

  setTimeout(() => checkAblumStatus(statusID), 1000);
}
Radonirina Maminiaina
  • 6,958
  • 4
  • 33
  • 60