Search code examples
angularobservablenedb

Accessing NeDB find() results


I'm making an app with Angular 2 and Electron and using NeDB as a data storage.

The search service is intended to handle operations with DB, for now I want it to load whole database and return it.

search.service.ts

import { Injectable } from '@angular/core';

import * as Datastore from 'nedb';
import * as path from 'path';

@Injectable()
export class SearchService {

  constructor() { }
  getData(){
    var db = new Datastore( {
      filename: path.resolve('src/assets/db.json'),
      autoload: true,
    });
    var result;
    db.find({}, function(err, docs) {
      result = docs;
     });
    console.log(result);
    return result;
  }

}

In my component I use a method to call getData() method of service upon initialization of component with ngOnInit hook.

But when I log results I get undefined.

While tinkering with search ervice I found out that docs I have in find() method are not accessible from outside the method and it seems like result = docs does nothing. So I was thinking that I need some async magic to make this work. I wanted to do this with Observables but couldn't achieve anything, probably was doing it incorrectly.


Solution

  • The find method is asynchronous and the callback function is not immediately executed, you can use promises like below:

    getData() {
        var db = new Datastore({
            filename: path.resolve('src/assets/db.json'),
            autoload: true,
        });
        return new Promise((resolve, reject) => {
            db.find({}, function(err, docs) {
                if(err) reject(err);
                resolve(docs);
            });
        })
    }
    
    someOtherFunc() {
      this.getData()
      .then((docs) => console.log(docs)) // here you will get it
      .catch((err) => console.error(err));
    }
    

    You can learn more about promises here

    In case you want to use Observables, you can do it like this:

    getData() {
        return new Rx.Observable(subscriber => {
            var db = new Datastore({
                filename: path.resolve('src/assets/db.json'),
                autoload: true,
            });
            db.find({}, function(err, docs) {
                if (err) subscriber.error(err);
                subscriber.next(docs);
            });
        })
    
    }
    
    someOtherFunc() {
        this.getData().subscribe(
            data => console.log("success", data),
            err => console.error("error", err)
        )
    }