Eamonn Mcn
Eamonn Mcn

Reputation: 23

Property 'pipe' does not exist on type 'Promise<HTTPResponse>'

I am trying to retrieve a list of products via a http call and then pipe and map the result before returning it to the subscribed function. I am using the ionic cordova advanced http plugin for ssl pinnign and making my requests. When i try to pipe the result of the request I get the error;

Property 'pipe' does not exist on type 'Promise'

Any ideas how to get around this?

import {Injectable} from '@angular/core';
import {environment} from '../environments/environment';
import {HttpClient, HttpHeaders, HttpResponse} from '@angular/common/http';
import { Observable, of, pipe, Observer } from 'rxjs';
import {AuthenticationService} from './authentication.service';
import 'rxjs/add/operator/map'
import { HTTP } from '@ionic-native/http/ngx';
import {map, startWith} from "rxjs/operators";

const ENDPOINT_URL = environment.endpointURL;
const CK = environment.consumerKey;
const CS = environment.consumerSecret;
@Injectable({
  providedIn: 'root'
})
export class PricesService {
  products: any;
  private user: any;
  items: any[] = [];
  page = 1;
  api_query = '';
  totalProducts = 1;

  providers: [
    HTTP // <-- List providers here
  ]

  constructor(
    public http: HTTP,
    public authenticationService: AuthenticationService
  ) { }


  getPrices(selectedQuantity): Observable<[]> {
    this.api_query = ENDPOINT_URL + 'wc/v3/product?tag=' + selectedQuantity + '?consumer_key=' + CK + '&consumer_secret=' + CS
    return this.http.get(this.api_query, '','').pipe(
      map(resp => {
        let data = resp['body'];

        // for (let post of data) {
        //   post.media_url = post['_embedded']['wp:featuredmedia'][0]['media_details'].sizes['medium'].source_url;
        // }
        return data;
      })
    );
  }

}
import { Component, OnInit } from '@angular/core';
import { AlertController } from '@ionic/angular';
import {PricesService} from '../prices.service';
import {AuthenticationService} from '../authentication.service';

@Component({
  selector: 'app-compare',
  templateUrl: './compare.page.html',
  styleUrls: ['./compare.page.scss'],
})
export class ComparePage implements OnInit {
  items: any[];

  constructor(
    public authenticationService: AuthenticationService,
    public alertCtrl: AlertController,
    public pricesService: PricesService
  ) { }

  ngOnInit() {
  }

  getPrices(selectedValue) {
    console.log("NEWLY SELECTD VALUE: "+selectedValue);
    //const user = this.authenticationService.getUser();
    console.log('Getting prices');
    this.pricesService.getPrices(selectedValue)
      .subscribe((data: any[]) => {
        this.items = data;
      });
  }
}

Upvotes: 0

Views: 2228

Answers (3)

Lucas Vazquez
Lucas Vazquez

Reputation: 1882

There are some differences between the typescript declarations and node-fetch code.

Typescript declares body attribute as ReadableStream<Uint8Array>, but fetch define a stream.PassThrough.

So, the next code works for me:

import { PassThrough } from "stream"

interface FetchResponse extends Response {
  readonly body: PassThrough & Response["body"]
  // Or, if you prefer, the following syntax:
  // readonly body: PassThrough & (ReadableStream<Uint8Array> | null)
}

const res = (await fetch(url)) as FetchResponse

Upvotes: 0

Rohit Sharma
Rohit Sharma

Reputation: 3334

Because this HTTP get request returns the promise, you need to convert the returned promise into an observable first. To convert the promise into the observable you can use the from operator provided by rxjs library

// import 'from' operator from rxjs
import { from } from 'rxjs';

return from(this.http.get(this.api_query, '','')).pipe(
    map(resp => // return something)
);

You can read more here about the Native HTTP module of Cordova.

Upvotes: 2

C.OG
C.OG

Reputation: 6529

An enhancement to @Rohit Sharma's answer:

I will suggest that you wrap the from call with the defer operator. This will make the observable "lazy" so that the underlying request is only made once you subscribe.

import { from, defer } from 'rxjs';


return defer(() => from(this.http.get(this.api_query, '','')))
  .pipe(
    map(resp => // return something)
  );

Upvotes: 3

Related Questions