How can I return success and the promise of an error with and without data?

I would like to return a promise and an object named output before or after calling $ http. Can anyone advise me how I can do this using the AngularJS framework and is very important with Typescript so that I can be sure that it works correctly?

  topicNewSubmit = (): ng.IPromise<any> => { var self = this; var myData1 = { abc: 123 } if (self.abc = 22) { // How can I return an OKAY promise from here? } if (self.abc = 33) { // How can I return an OKAY promise with myData1 from here? } if (self.abc = 88) { // How can I return a FAIL promise from here? } return self.$http({ url: self.url, method: "GET" }) .then( (response: ng.IHttpPromiseCallbackArg<any>): any => { var myData2 = { abc: 245 } // How can I return a promise and myData2. // return(myData2) gives an error with Typescript // How can I return a promise and no data // return gives an error with Typescript }, (error: ng.IHttpPromiseCallbackArg<any>): ng.IPromise<any> => { var myData3 = { abc: 345 } // Is this the correct way to return an unhandled reject with myData3 return self.$q.reject(myData); }); } 
+8
javascript angularjs typescript
source share
4 answers

Change Code fixed and TypeScript example added. Playground . The methods are correctly typed, you can check this by typing input errors, try to fix them;). I copied all the required interfaces from the angular definition file.

Edit # 2 : Here's the fixed version in the TypeScript Playground example above.

If I understand your question correctly, are you trying to determine the return type for the service method, stating that it returns a promise that will result in a specific object when resolved?

In this case, you are almost there, I divided your two examples of methods in separate blocks, since they require a different approach.

In the general case, I deleted the copy area ( self = this ), since you are using thick arrow methods that will automatically use the method in the outer lexical area. In short, there is no need to make a copy of the area, and in fact, in your example, I do not always point to the service (since you are copying the area inside the method, and not outside it).

Also note the definition of the angular promise (truncated):

 interface IDeferred<T> { resolve(value?: T): void; reject(reason?: any): void; } 

Thus, when entering angular Promise, only input will be added to solve the promise case, not the rejected case. Therefore, when calling your service, it checks that the result of the success handler is of the type that you defined, but the type of parameters in the error handler is of type any .

topicTest

For this method to work, you need to enter $q in your service and then use it to create your own deferred

 topicTest = (): IPromise<Foo> => { // return a promise which will result in a parameter of MyType upon resolving var deferred = this.$q.defer<Foo>(); // Type the deferred to get better 'intellisense' support if (this.abc = 99) { deferred.resolve(new Foo()); } if (this.abc = 88) { deferred.reject("You can pass in whatever you like to the reject case"); } return deferred.promise; }; 

topicNewSubmit

$http already returns promises, so all you have to do is plug them in by adding a then callback and returning from this method to associate other then callabacks with it.

In this case, the return type of your service method will be angular.IPromise<() => any> , where you can replace any with the type you want. The return type of the then method must match any type that you selected for the type placeholder in the return type of the service method.

 topicNewSubmit = () : IPromise<Foo> => { return this.$http({ url: this.url, method: "GET" }).then((response): Foo => { return new Foo(); }, (error) => { return "whatever you'd like, it does not have to correspond to Foo"; }); } 

Then you can use your service, for example

 MyService.topicNewSubmit().then((data) => { // data needs to be of type T, where T is the type you defined in the generic placeholder of IPromise<T> }, (error: any) => { // In the error case, the parameters are of type any }); 
+4
source share

Honestly, it seems to me that I am shooting in the dark with a sample code, but here is my solution.

Like Anzeo, I removed the links to self or this . $q and $http must be assigned somewhere.

 declare var $q: ng.IQService; declare var $http: ng.IHttpService; var topicNewSubmit = (): ng.IPromise<any> => { var deferred = $q.defer<any>(); var myData1 = { abc: 123 }; if (this.abc = 22) { deferred.resolve(); } else if (this.abc = 33) { deferred.resolve(myData1); } else if (this.abc = 88) { deferred.reject(); } else { $http({ url: this.url, method: "GET" }) .then(() => { deferred.resolve({ abc: 245 }); }, () => { deferred.reject({ abc: 345 }); }); } return deferred.promise; }; 
+3
source share

Answer

You cannot return what is not yet available unless you block all operations until you receive them. Since the JavaScript browser is (mostly) single-threaded, you do not want to block the stream while the file is loading. Therefore, you are returning a promise that will ultimately be resolved. The consumer needs to use the then function to ultimately get the value.

Humor

A promise is life. Its 🐒s all the way down 🌹

+2
source share

You can use the promise as

 var deferred = $q.deferred(); $http(api url and method) .success function() { deferred.resolve(); } .failure function() { deferred.reject(); } return deferred.promise; 
+2
source share

All Articles