any Property 'asObservable' does not exist on type '() => any'.ts(2339)

Error: Property 'asObservable' does not exist on type '() => any'.ts(2339) Error: Property 'subscribe' does not exist on type 'Subscription'. Did you mean 'unsubscribe'?ts(2551) Error: Property 'subscribe' does not exist on type 'void'.ts(2339) Here is my data.service.ts code

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from 'src/environments/environment';
import { BehaviorSubject } from 'rxjs';
@Injectable({
  providedIn: 'root'
})
export class DataService {
gifs = new BehaviorSubject<any>([]);
  constructor(private http: HttpClient) { }
  getTrendingGifs(){
    return this.http.get(`https://api.giphy.com/v1/gifs/trending?api_key=%${environment.giphyApiKey}&limit=50`)
    .subscribe((response: any) => {
     this.gifs.next(response.data);
    });
  }
  searchGifs(gifName: string){
    return this.http.get(`https://api.giphy.com/v1/gifs/search?q=${gifName}&api_key=%${environment.giphyApiKey}&limit=50`)
    .subscribe((response: any) => {
      this.gifs.next(response.data);
     });
  }
 getGifs(){
    return this.getGifs.asObservable(); 
  }
}

my search.component.ts code

export class SearchComponent implements OnInit {

  constructor(private dataService: DataService) { }

  ngOnInit(): void {
  }
  search(searchTerm: string){
    if (searchTerm !== ''){
      this.dataService.searchGifs(searchTerm)
      .subscribe((response: any) => {
        console.log('Search Data', response);
      });
    }

  }
}

my gifs.component.ts code

import { ThisReceiver } from '@angular/compiler';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { DataService } from '../data.service';

@Component({
  selector: 'app-gifs',
  templateUrl: './gifs.component.html',
  styleUrls: ['./gifs.component.css']
})
export class GifsComponent implements OnInit, OnDestroy {
  gifs: any[] = [];
  subscription: Subscription;

  constructor(private dataService: DataService) { }

  ngOnInit(): void {
    this.dataService.getTrendingGifs()
    this.subscription = this.dataService.getGifs()
     .subscribe((response: any) => {
     this.gifs = response;
     });
  }
  ngOnDestroy() {
    this.subscription.unsubscribe();
    
  }

}

Upvotes: 1

Views: 3146

Answers (1)

Nika Skakaia
Nika Skakaia

Reputation: 66

First as @akotech mentioned you have a typo. Instead of:

return this.getGifs.asObservable();

You need:

return this.gifs.asObservable();

Besides: Your approach of retrieving and populating data from server is wrong, you can subscribe to response on component level and then destroy that subscription when component is destroyed to avoid memory leaks.

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from 'src/environments/environment';
import { BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})

export class DataService {

  constructor(private http: HttpClient) { }

public getTrendingGifs(){
    return this.http.get(`https://api.giphy.com/v1/gifs/trending?api_key=%${environment.giphyApiKey}&limit=50`)
  }

 
public searchGifs(gifName: string){
    return this.http.get(`https://api.giphy.com/v1/gifs/search?q=${gifName}&api_key=%${environment.giphyApiKey}&limit=50`)
  }

}

Component:

import { OnDestroy, OnInit } from '@angular/core';
import { takeUntil } from 'rxjs/operators';

export class SearchComponent implements OnInit, OnDestroy {
  public destroy$: Subject<boolean> = new Subject<boolean>();

  constructor(private dataService: DataService) { }

  ngOnInit(): void {}

      search(searchTerm: string){
        if (!searchTerm || searchTerm == '') return;
          this.dataService.searchGifs(searchTerm)
          .pipe(takeUntil(this.destroy$))
          .subscribe((response: any) => {
            console.log('Search Data', response);
          });
        
      }

 ngOnDestroy() {
      this.destroy$.next(true);
      this.destroy$.unsubscribe();
  }

}

And:

import { ThisReceiver } from '@angular/compiler';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { DataService } from '../data.service';
import { takeUntil } from 'rxjs/operators';

@Component({
  selector: 'app-gifs',
  templateUrl: './gifs.component.html',
  styleUrls: ['./gifs.component.css']
})
export class GifsComponent implements OnInit, OnDestroy {
  public destroy$: Subject<boolean> = new Subject<boolean>();

  gifs: any[] = [];
  

  constructor(private dataService: DataService) { }

  ngOnInit(): void {
    
    this.dataService.getTrendingGifs()
     .pipe(takeUntil(this.destroy$))
     .subscribe((response: any) => {
     this.gifs = response;
     });

  }

  ngOnDestroy() {
     this.destroy$.next(true);
     this.destroy$.unsubscribe();
  }

}

Basically you don't need BehaviorSubject unless you have some other logic requiring it.

Upvotes: 2

Related Questions