-1

So I am currently attempting to modify a global object within a promise using the code below, however, when i console.log the object at the end, it returns 'undefined' for the key of 'id'. I'm a little confused as to why inside the success block of a promise it isn't setting the new key and value within the patient object. Thanks in advance!

    patient = { first_name: first_name, last_name: last_name, gender: gender, dob: dob }

        postgres.findPatient(patient)
          .then(function(success){

           patient.id = success.id

          })
          .catch(function(err){
            if (err.received === 0) {
              postgres.createPatient(patient)
                .then(function(success){
                    postgres.findPatient(patient)
                    .then(function(success){
                      patient.id = success.id
                    })
                })
                .catch(function(err){
                  if (err) console.log(err);
                })
            }
          })

console.log(patient) // yields

patient = { 
      first_name: 'billy, 
      last_name: 'bob', 
      gender: 'm', 
      dob: '1970-01-01' }
Danny Sun
  • 31
  • 7
  • Possible duplicate of [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Heretic Monkey Nov 08 '16 at 23:05
  • Try to console.log the object *at the end*, not right after you started the asynchronous call. – Bergi Nov 08 '16 at 23:35

2 Answers2

2

I'm a little confused as to why inside the success block of a promise it isn't setting the new key and value within the patient object.

It is, however, it is not executed immediately. That is how promises work.

When your code is run, it first begins the process of finding the patient. It then runs your console.log. When the database query has finished, it runs your .then function, which sets the id. The console.log is run before the patient.id is set.

If you put console.log(patient) in the then, right after patient.id = success.id, you should see the correct result.

You will get the same result if you put it in a then function after the catch (Read more about Promise Chaining). This would probably be the best place to write code that depends on the id. Like this:

    patient = { first_name: first_name, last_name: last_name, gender: gender, dob: dob }

    postgres.findPatient(patient)
      .then(function(success){

       patient.id = success.id

      })
      .catch(function(err){
        if (err.received === 0) {
          postgres.createPatient(patient)
            .then(function(success){
                postgres.findPatient(patient)
                .then(function(success){
                  patient.id = success.id
                })
            })
            .catch(function(err){
              if (err) console.log(err);
            })
        }
      })
      .then(function () {
         console.log(patient);

         // Do something with the id
      })
RyanZim
  • 6,609
  • 1
  • 27
  • 43
  • 1
    Good answer. I believe this is called [Chaining](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then#Chaining) – styfle Nov 09 '16 at 14:05
  • @styfle Yeah, edited the answer to add that link. Thanks! – RyanZim Nov 09 '16 at 14:31
0

Promises are asynchronous. You will only see the id key on the patient after the .then() has finished executing. Top level code is executed synchronously, so you're looking for the id before the promise has finished. You can only access the id inside a chained callback like .then() when the promise has guaranteed to finish.

Andy Ray
  • 30,372
  • 14
  • 101
  • 138