Search code examples
angular2-servicespouchdbangular2-components

Angular 4 PouchDB not updating service


Here is my service

export class LunchService {

  private db: any;
  lunches: any = [];

  constructor(
    private serverService: ServerService,
    private configService: ConfigService,
  ) {
    this.db = new PouchDB(configService.config.dbServer + '/' + configService.config.dbName);

    this.db.find({
      selector: { 'type': 'lunch' },
    }).then((result) => {
        // HERE
        this.lunches = result.docs;
    }).catch(function(err) {
      console.log(err);
    });
  }
}

Here is my compnent

export class ListingComponent {

  lunches: any = [];

  constructor(
    private lunchService: LunchService
  ) {
    // IS EMPTY WHEN SET IN SERVICE?
    this.lunches = this.lunchService.lunches;
  }
}

Why do the changes to the variable in the lunch service not reflect in the component? The lunches param in the controller does not get populated.

I'm guessing it's not in the change detection? But how to make this work?


Solution

  • To solve it, i ended up with the following below. As the data in the service will be shared this seems a satisfactory solution but i'm not sure it's the best.

    I extracted a new service for the pouch DB interaction to return an observable:

    export class PouchDbService {
    
      private db: any;
    
      constructor(
        private configService: ConfigService
      ) {
        this.db = new PouchDB(configService.config.dbServer + '/' + configService.config.dbName);
      }
    
      findDocs(searchParams) {
        return new Observable(observer => {
          this.db.find(searchParams).then((response) => {
            observer.next(response);
          }).catch((err) => {
            console.log(err);
          });
        }
        );
      }
    }
    

    Now in my lunch service i created a behavior subject:

    export class LunchService {
    
      lunches: any = new BehaviorSubject([]);
    
      constructor(
        private pouchDb: PouchDbService
      ) {
        this.getLunches().subscribe((response) => {
          this.lunches.next(response['docs']);
        });
      }
    
      getLunches() {
        return this.pouchDb.findDocs({
          selector: { type: { $eq: 'lunch' } }
        });
      }
    }
    

    And finally in my component i subscribe once again:

    export class ListingComponent implements OnInit {
    
      lunches: any;
    
      constructor(
        private lunchService: LunchService
      ) { }
    
      ngOnInit(): void {
        this.lunchService.lunches.subscribe((lunches) => {
          this.lunches = lunches;
        });
      }
    
    }
    

    It works ok and updates in the component fine. I'm just a little unsure if this is the right technique? Should i have to subscribe twice?

    Usually (non pouch db / general http calls) i could just assign the service variable, without being a behavior subject, and this would work fine and reflect any changes in the component / UI. But as the pouch uses a then i had to convert to observable and get the data that way.

    Any thoughts?