RamblerToning
RamblerToning

Reputation: 976

How do I wrap a return type with a promise in TypeScript?

I'm writing Angular 1.x with TypeScript, and I have a service (DataService) that's responsible for loading data. For a simple example, it queries for a node and returns a node. In the interface:

getNode(id: number): ng.IPromise<Node>;

and the implementation:

  getNode(id: number) {
            return this.ajaxService.getNode(id)
                .then((result: ng.IHttpPromiseCallbackArg<Node>) => {
                    return new Node(result.data.ID, result.data.Name);
                });
        }

However, I would like to introduce another service that stores these results and returns them if I've already queried for them before. So something like:

getNode(id: number) {
        var loadedNode = this.storageService.nodes.filter(e => (e.ID == id));
        if (loadedNode.length > 0) {
            return loadedNode[0];
        }

        return this.ajaxService.getNode(id)
            .then((result: ng.IHttpPromiseCallbackArg<Node>) => {
                var n = new Node(result.data.ID, result.data.Name);
                this.storageService.nodes.push(n);
                return n;
            });
    }

However, the return type fails because it's expecting 'ng.IPromise' rather than just 'Node'. How can I wrap 'return loadedNode[0];' into some sort of promise return type rather than returning the actual object?

Upvotes: 1

Views: 2154

Answers (2)

devqon
devqon

Reputation: 13997

You can do it like this, using the $q-service:

getNode(id: number) {
    var deferred = this.$q.defer();

    var loadedNode = this.storageService.nodes.filter(e => (e.ID == id));
    if (loadedNode.length > 0) {
        // immediately resolve with the cached node
        deferred.resolve(loadedNode[0]);
    } else {
        // else load through service
        this.ajaxService.getNode(id)
            .then((result: ng.IHttpPromiseCallbackArg<Node>) => {
                var n = new Node(result.data.ID, result.data.Name);
                this.storageService.nodes.push(n);

                // resolve with the loaded node
                deferred.resolve(n);
            });
    }

    // return the promise to register callbacks
    return deferred.promise;
}

Usage:

myService.getNode(id).then((node) => {
    // success
}, () => {
    // error
});

Upvotes: 3

Ahmet Zeytindalı
Ahmet Zeytindalı

Reputation: 451

use $q.when(value, [successCallback], [errorCallback], [progressCallback])

you can change the return line with

return $q.when(loadedNode[0]);

more info at angular $q

Upvotes: 1

Related Questions