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.
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)
)
}