Angular 2 and TypeScript Promises
<p>I'm trying to use the <code>routerCanDeactivate</code> function for a component in my app. The simple way to use it is as follows: </p>

<pre><code>routerCanDeactivate() {
    return confirm('Are you sure you want to leave this screen?');
}
</code></pre>

<p>My only issue with this is that it's ugly. It just uses a browser generated confirm prompt. I really want to use a custom modal, like a Bootstrap modal. I have the Bootstrap modal returning a true or false value based on the button they click. The <code>routerCanDeactivate</code> I'm implementing can accept a true/false value or a promise that resolves to true/false. </p>

<p>Here is the code for the component that has the <code>routerCanDeactivate</code> method:</p>

<pre><code>export class MyComponent implements CanDeactivate {
    private promise: Promise&lt;boolean&gt;;

    routerCanDeactivate() {
        $('#modal').modal('show');
        return this.promise;
    }

    handleRespone(res: boolean) {
        if(res) {
            this.promise.resolve(res);
        } else {
            this.promise.reject(res);
        }
    }
}
</code></pre>

<p>When my TypeScript files compile, I get the following errors in the terminal: </p>

<pre><code>error TS2339: Property 'resolve' does not exist on type 'Promise&lt;boolean&gt;'.
error TS2339: Property 'reject' does not exist on type 'Promise&lt;boolean&gt;'.
</code></pre>

<p>When I try to leave the component, the modal starts, but then the component deactivates and doesn't wait for the promise to resolve. </p>

<p>My issue is trying to work out the Promise so that the <code>routerCanDeactivate</code> method waits for the promise to resolve. Is there a reason why there is an error saying that there is no <code>'resolve'</code> property on <code>Promise&lt;boolean&gt;</code>? If I can work that part out, what must I return in the <code>routerCanDeactivate</code> method so that it waits for the resolution/rejection of the promise?</p>

<p>For reference, <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/es6-promise/es6-promise.d.ts">here is the DefinitelyTyped Promise definition</a>. There is clearly a resolve and reject function on there.</p>

<p>Thanks for your help.</p>

<p><strong>UPDATE</strong></p>

<p>Here is the updated file, with the Promise being initialized:</p>

<pre><code>private promise: Promise&lt;boolean&gt; = new Promise(
    ( resolve: (res: boolean)=&gt; void, reject: (res: boolean)=&gt; void) =&gt; {
        const res: boolean = false;
        resolve(res);
    }
);
</code></pre>

<p>and the <code>handleResponse</code> function: </p>

<pre><code>handleResponse(res: boolean) {
    console.log('res: ', res);
    this.promise.then(res =&gt; {
        console.log('res: ', res);
    });
}
</code></pre>

<p>It still doesn't work correctly, but the modal shows up and waits for the response. When you say yes leave, it stays on the component. Also, the first <code>res</code> that is logged is the correct value returned from the component, but the one inside <code>.then</code> function is not the same as the one passed in to the <code>handleResponse</code> function.</p>

<p><strong><em>More Updates</em></strong></p>

<p>After doing some more reading, it appears that in the <code>promise</code> declaration, it sets the <code>resolve</code> value, and the <code>promise</code> has that value no matter what. So even though later on I call the <code>.then</code> method, it doesn't change the value of the <code>promise</code> and I can't make it true and switch components. Is there a way to make the <code>promise</code> not have a default value and that it has to wait until the its <code>.then</code> method is invoked?</p>

<p>Updated functions:</p>

<pre><code>private promise: Promise&lt;boolean&gt; = new Promise((resolve, reject) =&gt; resolve(false) );

handleResponse(res: any) {
    this.promise.then(val =&gt; {
        val = res;
    });
}
</code></pre>

<p>Thanks again for the help.</p>

<p><strong><em>Last Update</em></strong></p>

<p>After looking at many suggestions, I decided to create a <code>Deferred</code> class. It's worked pretty well, but when I do the <code>deferred.reject(anyType)</code>, I get an error in the console of:</p>

<pre><code>EXCEPTION: Error: Uncaught (in promise): null
</code></pre>

<p>This same thing happens when I pass in <code>null</code>, a <code>string</code>, or a <code>boolean</code>. Trying to provide a <code>catch</code> function in the <code>Deferred</code> class didn't work.</p>

<p><strong><em>Deferred Class</em></strong></p>

<pre><code>export class Deferred&lt;T&gt; {
    promise: Promise&lt;T&gt;;
    resolve: (value?: T | PromiseLike&lt;T&gt;) =&gt; void;
    reject:  (reason?: any) =&gt; void;

    constructor() {
        this.promise = new Promise&lt;T&gt;((resolve, reject) =&gt; {
            this.resolve = resolve;
            this.reject  = reject;
        });
    }
}
</code></pre>