3

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.

Ivan Bespalov
  • 147
  • 1
  • 12

1 Answers1

6

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)
    )
}
Dhyey
  • 4,275
  • 3
  • 26
  • 33
  • Thank you very much for clear and quick answer! But I wanted to know if I can use observables instead of promises because of their consistent nature. I want to use this service to do searches in db and provide different information, which creates more hustle with promises rather than with observables, as I gathered. – Ivan Bespalov Jul 07 '17 at 09:28
  • @IvanBespalov i have edited my answer to include observable approach – Dhyey Jul 07 '17 at 10:51
  • Thank you so much, great solution... you also use `async/await` for promise stuff – Peyman Majidi Mar 09 '23 at 13:46