3

I've looked at similar questions on StackOverflow but none of them match my specific problem:

I have a TypeScript function in an Angular 6 service, calling a function in another service like this:

Service1:

myArray: Array<IMyInterface>

...

getArray(): Observable<IMyInterface[]> {

    this.myArray= this.service2.getAnArray(1);
    return Observable.of(this.myArray);
}

Service2

getAnArray(myEntityId): Array<IMyInterface> {
  const myArray2: IMyInterface[] = [];

  this.getConnection().then(connection => {
    connection.invoke('GetEntityById', myEntityId).then((someJson: any) => {
      someJson.forEach( x => myArray2.push(x));       
      return myArray2;
    })
  }); 
}

It gives me the error in Service2 A function whose declared type is neither 'void' nor 'any' must return a value.

I need to return myArray2 after connection.invoke('GetEntityById', myId) has resolved, as the array is only populated after that resolves, which is why I try to do it inside then.

How do I do this?

4
  • may be you can add myArray on component instance like this.myArray and use it wherever you want in component rather than returning it? Commented Aug 28, 2018 at 4:08
  • return connection as well? Commented Aug 28, 2018 at 4:09
  • No, thanks but neither of those work. I've updated the question with more details of the context. The connection shouldn't be returned from Service2, as it's important that any use of it is strictly encapsulated in Service2 Commented Aug 28, 2018 at 4:17
  • Possible duplicate of How do I return the response from an asynchronous call? Commented Aug 28, 2018 at 4:45

2 Answers 2

1

This may/may not suit your needs, but you could just return the Promise from your service method, eg:

getAnArray(myEntityId) {
  const myArray: IMyInterface[] = [];

  // Note the return here
  return this.getConnection().then(connection => {
    return connection.invoke('GetEntityById', myEntityId).then((someJson: any) => {
      someJson.forEach( x => myArray.push(x));       
      return myArray;
    })
  }); 
}

Your calling code would then look like

getAnArray(someId).then(function(theArray) {. . .});
Sign up to request clarification or add additional context in comments.

3 Comments

I think another return is missing before connection.invoke.
No, getAnArray isn't a promise
Then what you want to do isn't really possible I don't think. If you're relying on asynchronous behavior, I don't know of a graceful way to convert that to synchronous behavior for calling code outside of async/await which is just promises anyway.
1

A bit late for this. But someone may find this helpful. You can use Async/Await for this. The reason is every time 'await' occurs, it will hold the thread until the job is done.

 async getAnArray(myEntityId) {
    await this.getConnection();
    try {
      let result = await connection.invoke('GetEntityById', myEntityId).then((someJson: any) => {
      someJson.forEach(x => myArray.push(x));
      return myArray;
      })
   } catch (err) {
  console.log(err);
}

}

To get results (will return a promise):

this.getAnArray(myEntityId).then((data) => {
  console.log('data' , data);
 
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.