Property 'then' does not exist on type Observable
Asked Answered
P

3

21

I'm new to angular 2 and I'm trying to make a REST GET request, but I'm getting this error when trying:

error TS2339: Property 'then' does not exist on type 'Observable<Connection[]>'.

Here is the component calling the service:

import { Component, OnInit} from '@angular/core';
import { Router }           from '@angular/router';

import { Connection }       from './connection';
import { ConnectionService }      from './connection.service';

let $: any = require('../scripts/jquery-2.2.3.min.js');

@Component({
  selector: 'connections',
  styleUrls: [ 'connections.component.css' ],
  templateUrl: 'connections.component.html',
  providers: [ConnectionService]
})

export class ConnectionsComponent implements OnInit {

  connections: Connection[];
  selectedConnection: Connection;

  constructor(
    private connectionService: ConnectionService,
    private router: Router) { }

  getConnections(): void {
    this.connectionService.getConnections().then(connections => {
      this.connections = connections;
    });
  }

  ngOnInit(): void {
    this.getConnections();
  }

  onSelect(connection: Connection): void {
    this.selectedConnection = connection;
  }

  gotoDetail(): void {
    this.router.navigate(['/connectiondetail', this.selectedConnection.id]);
  }
}

Here is the ConnectionService:

import { Injectable }     from '@angular/core';
import { Http, Response } from '@angular/http';
import { Connection }     from './connection';
import { Observable }     from 'rxjs/Observable';

@Injectable()
export class ConnectionService {

  private connectionsUrl = 'https://localhost/api/connections';  // URL to web API

  constructor (private http: Http) {}

  getConnections(): Observable<Connection[]> {
    return this.http.get(this.connectionsUrl)
                    .map(this.extractData)
                    .catch(this.handleError);
  }

  private extractData(res: Response) {
    let body = res.json();
    return body.data || { };
  }

  private handleError (error: Response | any) {
    // In a real world app, we might use a remote logging infrastructure

    let errMsg: string;

    if (error instanceof Response) {
      const body = error.json() || '';
      const err = body.error || JSON.stringify(body);
      errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
    } else {
      errMsg = error.message ? error.message : error.toString();
    }

    console.error(errMsg);

    return Observable.throw(errMsg);
  }
}

How do I fix this error?

Thank you,

Tom

Pires answered 6/12, 2016 at 0:3 Comment(0)
S
28

An Observable doesn't have a promise-like method as then. In your service you are performing an http call which returns an Observable and you map this Observable to another Observable.

If you really want to use the promise-style API, you need to convert your Observable to a promise using the toPromise operator. This operator is not available by default so that you also need to import it once in your project.

import 'rxjs/add/operator/toPromise';

Using promises is okay, but there are some good reasons to use the Observable APIs directly. For details, please see this blog post advertising the usage of Observables.

If you want to use the Observable API directly then replace your then call with a subscribe call. But remember that every subscription also needs to be cancelled when your component gets destroyed.

getConnections(): void {
  this.subscription = this.connectionService.getConnections()
    .subscribe(connections => this.connections = connections);
}

ngOnDestroy() {
  this.subscription.unsubscribe();
}

Another option when working with Observables is to assign the resulting Observable to a field in your component and then use the async pipe. Doing so, Angular will handle the subscriptions for you.

Savdeep answered 6/12, 2016 at 0:23 Comment(0)
S
7

in between add .toPromise() to make it a promise

Swinish answered 14/5, 2019 at 10:0 Comment(0)
C
1

for Angular I solved it in the following way, I just needed to add the .toPromise method to convert the observer.

GetUsersData() {
    const UsuariosCollection = this.afs.collection('usuarios').get();

    UsuariosCollection.toPromise().then((snapshot) => {
      snapshot.forEach((doc) => {
        console.log(doc.id+" => "+doc.data());        
      });
    });
  }
Coranto answered 9/5, 2021 at 2:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.