2

I currently am managing code that has this function

public getData(somei: Somei): Promise<SomeD> {

       return new Promise((resolve, reject) => {
               this.getSomeD(somei).subscribe((someData: SomeD) => {
                   resolve(someData);
               });
        });

    }

This works fine. I would like to add a then to perform an action after the code above executes but I dont seem to get it to work. I tried it like

public getData(somei: Somei): Promise<SomeD> {

       return new Promise((resolve, reject) => {
               this.getSomeD(somei).subscribe((someData: SomeD) => {
                   resolve(someData);
               });
        }).then(()=>{callanotherFunction()});

    }

but I get the typescript error

 Type 'Promise<void>' is not assignable to type 'Promise<SomeD>'.

I imagine I have to return the right object type? I should say I am not that familiar with promises.

JennyToy
  • 588
  • 4
  • 19
  • 1
    *This works fine*: no, it doesn't. If the obervable errors, then your returned promise never resolves, but never errors either. So the caller has no way to know that an error occurred. This is an anti-pattern. Use Observable.toPromise(), or simply return the Observable directly instead of transforming it into a promise. You will have to learn observables to work efficiently with Angular. So now is the best time to start learning them. All you should have is `return this.getSomeD(somei).pipe(tap(() => callanotherFunction()));` – JB Nizet Mar 27 '18 at 17:00
  • 1
    I assume your `callanotherFunction` is a void function. I suspect you rather only want to return your new Promise. – k0pernikus Mar 27 '18 at 17:00
  • 1
    You also might want to look up `await` and how it differs from using `then` callbacks. – k0pernikus Mar 27 '18 at 17:01
  • 1
    In regards that you are not familiar with promises, I have recently written an answer to a somewhat different question, yet you still might find it useful: https://stackoverflow.com/a/47413446/457268 – k0pernikus Mar 27 '18 at 17:08

3 Answers3

4

The line

.then(()=>{callanotherFunction()});

Is the problem. Since that anonymous function does not return anything (it only invokes callanotherFunction), your promise has changed from returning a SomeD to returning void, which is the error typescript is pointing out to you.

As you say, the solution is to return the right thing. In this case, I think you have two options. Either save the promise to a variable, do your .then on that, then return the original. Or you can intercept the result of the original and just forward it in your anonymous function.

Here's an example of both:

const prom = new Promise((resolve, reject) => {
    this.getSomeD(somei).subscribe((someData: SomeD) => {
        resolve(someData);
    });
});

// Do your code when promise resolves, but return original:
prom.then(() => { callanotherFunction() });
return prom;

Or, to just forward the result:

return new Promise((resolve, reject) => {
    this.getSomeD(somei).subscribe((someData: SomeD) => {
        resolve(someData);
    });
}).then(result => { callanotherFunction(); return result; }); // Forward the result

Using either of those, the return type will remain as Promise<SomeD>.

CRice
  • 29,968
  • 4
  • 57
  • 70
2

It's complaining because your second promise (the then()) the is not returning anything, but your signature says it will. If callanotherFunction returns something you can return that by removing the braces in the then body:

then(()=>callanotherFunction());

or explicitly return something:

.then(()=>{
   return callanotherFunction()
});

If callanotherFunction() doesn't return anything, then your signature is wrong and should be changed to reflect this:

public getData(somei: Somei): Promise<Void> {

You can also pass the value from the first promise into then and return it making callanotherFunction() just a side-effect:

 .then((someData)=>{
   callanotherFunction()
   return someData
});

This assumes that callanotherFunction() does not perform some async operation that needs to happen first.

Better than all of this is probably to take @jb-nizet's advice in the comments and use the observables directly.

Mark
  • 90,562
  • 7
  • 108
  • 148
-1

Specify the promise type to be returned

return new Promise<SomeD>(/* blablabla */);
Thiago Martins
  • 119
  • 2
  • 9