Chris
Chris

Reputation: 442

Passing a Promise from one Service Call To Another in Angular

So I've got a service call going out to the back end and saving an object, the call has a promise set up to return a number.

That call looks like this

    saveTcTemplate(item: ITermsConditionsTemplate): ng.IPromise<number> {
        item.modifiedDate = new Date();
        return this.$http.post(this.api + '/SaveTcTemplate', item)
            .then(this.returnData); 
    }

    returnData = (response: any) => {
        return response.data;
    };

This is when creating a new object, all the fields are set to their needed values, passed to save in, then called to be displayed.

This is the get function used to pull the object after it's been saved.

    getTermsConditions(id: number): ng.IPromise<ITermsConditionsTemplate> {
        return this.$http.get(this.api + '/GetTermsConditions',
            {
                params: {
                    id: id
                }
            }).then(this.returnData);
    }

This is the initial construction, saving, and getting, of the object

                this.newTemplate.copyId = 0;
                this.newTemplate.id = 0;
                this.newTemplate.isLibrary = true;
                this.newTemplate.studyFacilityScheduleId = this.studyFacilityScheduleId;
                this.studyTermsConditionsService.saveTcTemplate(this.newTemplate)
                    .then(this.studyTermsConditionsService.getTermsConditions)
                    .then(this.setTemplateData);

When set up like this I can successfully save a new item, and have its id (the ng.IPromise part) returned to me, and passed into my Get service call.

The problem is, when set up this way, this.$http.get comes back undefined. From what I think I understand from other stack overflow issues that are similar, it is happening because I called the function without explicitly passing anything into it's parameter when I say

.then(this.studyTermsConditionsService.getTermsConditions)

To test this I also set up the save and get like this

                var data: any;
                data = this.studyTermsConditionsService.saveTcTemplate(this.newTemplate);
                this.studyTermsConditionsService.getTermsConditions(data)
                    .then(this.setTemplateData);

And that worked, sort of. $http.Get was recognized, and could be used, but the problem with this setup was; due to the asynchronous nature of ng.IPromise the data isn't being sent to my Get function as the promised number value. It's being sent as type $$promise which results in the parameter in my get function being NaN.

So one way I'm passing a usable value, i.e. 32, but I'm not explicitly passing this value, so $http.get is undefined.

The other way, I am explicitly passing a parameter, so $http.get is recognized, and usable, but the explicitly called parameter is of type $$promise, not type number, It seems, unfortunately, the ng.IPromise< number > is not resolved by time I call my Get function.

How do I proceed from here??

Upvotes: 2

Views: 1079

Answers (1)

Pankaj Parkar
Pankaj Parkar

Reputation: 136164

I guess you are messed up with this. As you directly pass the function reference as parameter it lost with the context. You should call them explicitly like below.

Code

this.newTemplate.copyId = 0;
this.newTemplate.id = 0;
this.newTemplate.isLibrary = true;
this.newTemplate.studyFacilityScheduleId = this.studyFacilityScheduleId;
this.studyTermsConditionsService.saveTcTemplate((response) => this.newTemplate(response))
    .then((response) => this.studyTermsConditionsService.getTermsConditions(response))
    .then((response) => this.setTemplateData(response));

Otherwise you could make your function to use of arrow function which would help to available this context inside function.

saveTcTemplate(item: ITermsConditionsTemplate): ng.IPromise<number> { .. }

should be

saveTcTemplate = (item: ITermsConditionsTemplate): ng.IPromise<number> => { .. }

And

getTermsConditions(id: number): ng.IPromise<ITermsConditionsTemplate> { .. }

should be

getTermsConditions = (id: number): ng.IPromise<ITermsConditionsTemplate> => { .. }

Upvotes: 2

Related Questions