0

I am calling a function which has a subscriber function in it. This function must return an array, but it's giving an error:

subscription is missing.

get():obeservable<cat[]>{
       return this.service.getsamples().subscriber(response=>{
              return <cat[]>(response);
       });
}

getSamples(){
       return this.http.get(this.url)
            .map(response=>{
             return <cat[]>response
            });
}

How to achieve this?

Vega
  • 27,856
  • 27
  • 95
  • 103
Mounica
  • 170
  • 1
  • 4
  • 14
  • You can't return data from within `subscribe`. You have to work with Observables up until the point where you actually need the data (e.g. your component). Use the [async pipe](https://angular.io/api/common/AsyncPipe) in your template to get the data from an Observable or subscribe in your component and assign the emitted data inside `subscribe` to a global variable in your component. See: https://stackoverflow.com/a/37608134/9423231 – frido Aug 08 '19 at 10:27
  • You might want to take a look at my library ngx-rxcache, it simplifies the process of managing http responses https://medium.com/@adrianbrand/angular-state-management-with-rxcache-468a865fc3fb – Adrian Brand Aug 08 '19 at 21:21

2 Answers2

0

First, if you want to map the data return from an Observable to something else, pass the map() operator to the Observable's pipeline. Like this:

getSamples(): Observable<Cat[]>{
  return this.http.get(this.url).pipe(map(response => { .... });
}

But if the get request is simply going to return the Cat[] data, then you dont have to map it:

getSamples(): Observable<Cat[]>{
  return this.http.get(this.url);
}

Secondly, if you want to active the Observable returned from getSamples(), subscribe() to it not subscriber() to it.

And it really important to know that the subscribe() function is going to return a subscription of the Observable you subsrcibed to, not the data it contain

Returning an data from a observable inside a function is not a good approach because get() is a asynchronous function, it need to wait for your http request to complete first in order to return the right data/error. So the better approach is to active the observable somewhere outside and pass the logic that need the cat[] data into it:

ngOnInit() {
   this.service.getsamples().subscribe(response => {
       console.log(response) 
      // Do stuffs with respone data
   },err =>{
      console.log(err)
      // Do things with error
   });
}
Ethan Vu
  • 2,911
  • 9
  • 25
  • You can't return anything from within the `next` callback inside `subscribe`. Your `get()` function isn't returning `cat[]`. – frido Aug 08 '19 at 10:17
-2

Simple observable setup would be something like:

@Injectable()
export class SomeService {
  constructor(private readonly httpClient: HttpClient) {}

  public getData(): Observable<Cat[]> {
    return this.httpClient.get<Cat[]>('http://something.com')
      .pipe(catchError(err) => this.handleError(err));
  }

  private handleError(err: HttpErrorResponse): Observable<Cat[]> {
    // do something
    const result: Cat[] = [];
    return of(result);
  }
}

And hook up to it:

@Component({...})
export class SomeComponent implements OnDestroy {
  constructor(private readonly service: SomeService) {}

  public doSomething(): void {
    this.service.getData()
      .subscribe((x: Cat[]) => {
        alert(`Received ${x.length} cats`);
      });
  }
}

At some point, the Angular HttpClient got somewhat smarter and will handle mapping the return types, so you can make your own generic HttpService of some description and make use of this.httpClient.get<T>(...), or just on a per-usage basis do as the above and ensure you provide your type to the method this.httpClient.get<Cat[]>(...).

Krenom
  • 1,894
  • 1
  • 13
  • 20
  • Do not unsubscribe from the observer function. – Adrian Brand Aug 08 '19 at 01:48
  • Depends on whether you're doing a one-off call or expecting more data to come in. At the very least it's a good idea to ensure you clean up after yourself - whether you do that at the end of your call or do it on an ngOnDestroy is up to you, – Krenom Aug 08 '19 at 06:10
  • If you try and self unsubscribe like that and the observable emit straight away then the sub is undefined as the observer function is run before the sub is assigned. Try it with a behavior subject and see what happens. – Adrian Brand Aug 08 '19 at 07:32
  • hi Adrian Brand, I am using "Subject " from rxjs and its returning object and I am not sure is that ok to use "Subject " or it has any side effects or I need to go for pipe and map operator ....?? – Mounica Aug 08 '19 at 16:56