0

Follow-up to an earlier answered question I had earlier about Promises. I am able to get the called class returning a value, but naturally my caller class has moved on without the value.

My Startup.vue caller:

export default {
         methods: {
             onButtonTap() {
                 let person = personService.retrievePerson(this.id).then(function(val) {
                        console.log("===> received val: " + val);
                        this.person = JSON.stringify(val);
                         console.log("===> received person: " + person);
                         if (person) {
                             console.log("Welcome " + person.firstName + " " + person.lastName);                                 
                         } else {
                             console.log("Null Person returned for  " + this.id));                                 
                         }
                    }
             }
         }
    }

The PersonService.js file

export default class PersonService {

  async retrievePerson(scannedId) {
    var Person;
    const httpModule = require("tns-core-modules/http");

    let headers = {
        "Authorization": config.API_KEY,
        "Content-Type": 'application/json'
    };

    console.log("===> PersonService.retrievePerson() headers: \"" +  JSON.stringify(headers) + "\"");
        let personAPI = config.API + "/person/" + scannedId;
        console.log("===> PersonService.retrievePerson() URL: \"" +  personAPI+ "\"");

  return new Promise(resolve => {
            httpModule.request({
                url: personAPI,
                headers: headers,
                method: "GET"
            }).then((response) => {
                let status = response.statusCode;
                if (status === 200) {
                    let content = JSON.parse(response.content);
                    Person = JSON.parse(response.content);
                    console.log("===> returned [200] PersonService.retrievePerson() response: \"" +  JSON.stringify(Person) + "\"")
                } else if (status === 404) {
                    console.log("===> returned [404] ... returning null ");
                }
            }).then(() => {
                console.log("===> PersonService.retrievePerson().then() has Person : " + JSON.stringify(Person));
                resolve(Person);
            }).catch((err) => {
                console.error("retrievePerson() caught error: " + JSON.stringify(err));
            });
        });

}

And naturally, the console shows that by the time the Promise has resolved, my code has moved on:

CONSOLE LOG file:///app/components/Stazrtup.vue:123:0: '===> Startup calling PersonService'
CONSOLE LOG file:///app/services/PersonService.js:81:20: '===> PersonService.retrievePerson() headers: "{"Authorization":"123","Content-Type":"application/json"}"'
CONSOLE LOG file:///app/services/PersonService.js:83:24: '===> PersonService.retrievePerson() URL: "https://myapi.com/person/1"'
T
CONSOLE LOG file:///app/services/PersonService.js:95:32: '===>  returned [200] PersonService.retrievePerson() response: "{"personId":1,"firstName":"Sid","lastName":"Vicious","dateOfBirth":"1956-08-01","lastFourSSN":"0123","address":{"addressId":1,"addressLine1":"Main St","addressLine2":"","city":"Metropolis","state":"CO","zip":"80111","latitude":"123","longitude":"-105"}}"'
CONSOLE LOG file:///app/services/PersonService.js:100:28: '===> PersonService.retrievePerson().then() has Person : {"personId":1,"firstName":"Sid","lastName":"Vicious","dateOfBirth":"1956-08-01","lastFourSSN":"0123","address":{"addressId":1,"addressLine1":"Main St","addressLine2":"","city":"Metropolis","state":"CO","zip":"80111","latitude":"123","longitude":"-105"}}'
CONSOLE LOG file:///app/components/Startup.vue:126:0: "'===> received val: [object Object]'"

I am missing how to get this to await for the promise to return. I tried assigning the Promise to a variable and returning that. I tried making the OnButtonTap asych, but that isn't allowed.
I tried the suggestion @michich112 suggested, but I don't think I did it right either. It feels like its close...but countless revisions have not worked for me.

UPDATE

It occurred to me that I am asking this wrong. Here is what I am trying to accomplish.

  1. I have a Vue page that contains a button.
  2. When that button is clicked, a value is passed to a HTTP service that will return a response.
  3. That response will indicate which page, if any, should be navigated to.

So I need to get the response from that service to determine page flow before I can proceed.

Here is an example of what I am trying to solve: https://play.nativescript.org/?template=play-vue&id=gIbxXm&v=6

sonoerin
  • 5,015
  • 23
  • 75
  • 132

1 Answers1

0

You can't block the view and await for a promise to resolve what you have to do is assign the resolved response to a reactive variable, that's exactly what you did with this.person but the problem you tested on a out scooped variable person. try this

export default {
         methods: {
             onButtonTap() {
                 personService.retrievePerson(this.id).then(function(val) {
                        console.log("===> received val: " + val);
                        let person = val;
                         console.log("===> received person: " + person);
                         if (person) {
                             console.log("Welcome " + person.firstName + " " + person.lastName);                                 
                         } else {
                             console.log("Null Person returned for  " + this.id));                                 
                         }
                    }
             }
         }
    }
Quantumass
  • 826
  • 6
  • 11
  • To confirm, I can leave my PersonService as is, because the calling Vue class will basically invoke the http call and get the result? I ask because nothing happens after the personService call from Vue – sonoerin Apr 08 '20 at 19:03
  • exactly, nothing will happen but in this case `this.person` will contain the result of the invoked http request and you can use it on the view or where ever you want – Quantumass Apr 08 '20 at 19:13
  • So because I am trying to react to the returned http request value in my vue file, this cannot work as is? I have the code you show above but I still get the same sequence of output - the method finishes before the http finishes, and I can no longer react (direct to another page) based off that – sonoerin Apr 08 '20 at 19:34
  • I think you didn't add person to the state so your promise throw an error, I updated the answer can you try it again and tell me what are the new logs you have – Quantumass Apr 08 '20 at 19:44
  • I have your code in place and I see everything populated properly. But this just means the code has moved on and not waiting for the http call to finish. I added a console.log after the personService.retrievePatient call...and its undefined before the service call executes – sonoerin Apr 09 '20 at 12:38
  • I'm sorry I can't understand what are you trying to achieve, would you please update your question with the current status so I can understand more – Quantumass Apr 09 '20 at 12:44
  • My apologies, I updated the original post to hopefully clarify my question. – sonoerin Apr 09 '20 at 16:08