-1

Hello I have a PouchDB service that retrieves some data and return a promise with it. I want to convert that promise to an observable and then subscribe in ngOnInit so the model gets updated.

I made an implementation of a service with a method that returns the observable, but it's not working (the data does not get reflected on DOM):

Component HTML:

<h1>{{title}}</h1>
<ul>
  <li *ngFor="let platform of platforms">
    <a href="#">{{ platform }}</a>
  </li>
</ul>

Component TS:

import { Component, OnInit } from '@angular/core';
import { PouchDbBuilder } from './PouchDbBuilder';
import { PlatformsService } from './services/PlatformsService';

@Component({
  selector: 'platforms',
  templateUrl: './platforms.component.html'
})
export class PlatformsComponent implements OnInit {
  title : string;
  platforms: Array<string>;
  private platformsService;

  constructor() {
    this.title = "All Platforms";
    let serviceName = 'http://xxxx.net:5984/';
    let pouchDbBuilder = new PouchDbBuilder(serviceName);
    this.platformsService = new PlatformsService(pouchDbBuilder);
  }

  ngOnInit() {
    this.platformsService.getPlatforms().subscribe(platforms => {
      this.platforms = platforms;
    });
  }
}

Service TS:

 import { Injectable } from '@angular/core';
    import {PouchDbBuilder} from './PouchDbBuilder';
    import {PlatformsDataProvider} from './PlatformsDataProvider';
    import { Observable } from "rxjs/Observable";

    @Injectable()
    export class PlatformsService {

    private platformsProvider;

    constructor(private pouchDbBuilder: PouchDbBuilder) {
      this.platformsProvider = new PlatformsDataProvider(this.pouchDbBuilder);
    }

    getPlatforms(): Observable<Array<string>> {
     return new Observable(observer => {
      this.platformsProvider.getPlatforms().then(platforms => {
        observer.next(platforms);
      }).catch(err => {
        console.error(err);
      });
    });
   }
  }

This only works if i add "this.ngZone.run" after the suscribe to the ngOnInit, like this:

ngOnInit() {
    this.platformsService.getPlatforms().subscribe(platforms => {
      this.ngZone.run(() => {
        this.platforms = platforms;
      });
    });
  }

But this way it's like cheating because i'm forcing the update on DOM.

Can anyone tell me what i'm doing wrong?

CoF
  • 1
  • 3
  • what is a pouch db builder here , can't you directly call the http get which returns a observable by defualt – Rahul Singh Jul 28 '17 at 08:41
  • PouchDbBuilder is a custom library that make its own HTTP calls, using Xhr library, not Angular http. PlatformsDataProvider does the same. – CoF Jul 28 '17 at 08:50

2 Answers2

0
import 'rxjs/add/observable/fromPromise';

var subscription = Observable.fromPromise(your promise data);
subscription.subscribe(data => /* Do anything with data received */,
                       error => /* Handle error here */);

UPDATE

   var promise = this.platformsProvider.getPlatforms().then(platforms => {
        return platforms.json();
      });

 return Observable.fromPromise(promise);
Rahul Singh
  • 19,030
  • 11
  • 64
  • 86
  • i've changed the getPlatforms() so im returning the Observable.fromPromise but, also it's not showing the updated data on DOM, only if i use "this.ngZone.run(() => {this.platforms = platforms;});" after suscribe it 's working – CoF Jul 28 '17 at 08:58
0

You're not injecting the service into your component correctly.

You need to add the service that you're injecting into your component in the constructor.

Don't forget to also add the service to your providers in the module.

Taken from the Angular tutorial

import { MessageService } from './message.service';
...
constructor(private messageService: MessageService) { }
...
getHeroes(): Observable<Hero[]> {
  // Todo: send the message _after_ fetching the heroes
  this.messageService.add('HeroService: fetched heroes');
  return of(HEROES);
}
jriver27
  • 852
  • 5
  • 19