dbones
dbones

Reputation: 4504

This does not seem to be returning the correct object (Typescript)

I have created a small class, which wrappers around a generic callback function signature, and returns a promise.

however then it calls the handle menthod the _resolve is undefined.

/// <reference path="typings/es6-promise/es6-promise.d.ts" /> 
import rsvp = require('es6-promise'); 
var Promise = rsvp.Promise;

/**  * wrapper a callback style call into a promise  */ class
Promiseify<T> {
    private _promise : Promise<T>;
    private _resolve : (result?: T) => void;
    private _reject : (error: any) => void;

    /**
     * create wrapper, example: new Promiseify(call).promise
     * @param call example (handle) => yourDb.update(document, handle)
     */
    constructor(call:(handle:(error: any, result: T) => void) => void){

        this._promise = new Promise<T>((resolve, reject) =>{
            this._resolve = resolve;
            this._reject = reject;
            call(this.handle);
        });

    }

    handle(error: any, result: T) {
        if(error != null) this._reject(error);
        else this._resolve(result);
    }

    /**
     * get the es6 promise which can then be passed to external callers
     * @returns {Promise<T>} the es6 promise which this class creates.
     */
    get promise() : Promise<T>{
        return this._promise;
    } 
}

//the test rig 
new Promiseify<string>((handle)=> {
    handle(null, 'hello world');
}).promise.then((greeting: string)=> {
        console.log(greeting);
    });

am i missing something, btw the JS under the covers looks ok too

also if it helps I am running this on Node.JS, inside Webstorm 9.03

Upvotes: 0

Views: 86

Answers (2)

JLRishe
JLRishe

Reputation: 101700

You are passing this.handle into call(), so when call() calls it, this will be null and that is why your approach isn't working.

I'm not sure what would be most idiomatic in TypeScript, but you can do:

call(this.handle.bind(this));

or

call((error, result) => this.handle(error, result));

Alternatively, you could get rid of the handle method entirely, and do this:

this._promise = new Promise<T>((resolve, reject) => {
    call(function (error, result) {
        if (error) { reject(error); }
        resolve(result);
    });
});

but then that just leaves the question of why you need a class at all, when you could instead use an 8-line function that does the same thing:

function promisify<T>(call:(handle:(error: any, result :T) => void) => void) {
    return new Promise<T>((resolve, reject) => {
        call(function (error, result) {
            if (error) { reject(error); }
            resolve(result);
        });
    });
} 

Upvotes: 1

Dick van den Brink
Dick van den Brink

Reputation: 14529

You have two options here:

The first one is to declare the handle method as a property like so:

handle = (error: any, result: T) => {
    if(error != null) this._reject(error);
    else this._resolve(result);
}

Or change your call method so it calls it on the instance like below:

var that = this;
call(function(e, r) { that.handle(e, r); });

Upvotes: 1

Related Questions