Angular - In custom service after calling $http service and updating array value, its not updated outside the function - service

I created the custom service where I have empty array which is updated from json value which i called using $http service. But when I called that new array it doesn't give me updated array instead it gives me empty array.
But when i called the service from some other controller it gives me correct value.
service('categoryTree', ['$http', function($http) {
var categories = [];
$http.get('/json/categories.json').then(function (response) {
response.data.forEach(function (category) {
categories.push(category);
});
});
console.log(categories);//it gives empty array here
// I am trying to create a new function through this categories array value but it shows empty
return {
categories: categories
};
}])
Can somebody help me. Thanks a lot.

Related

AngularFire valueChanges with idField and non-existent document

If I call valueChanges on a Firestore document that doesn't exist, it returns undefined:
this.afs.doc('bad_document_ref').valueChanges().subscribe(snapshot => {
console.log(snapshot) // undefined
});
But if I call valueChanges on the same bad ref, but I pass in the idField parameter, it returns an object with just the id:
this.afs.doc('bad_document_ref').valueChanges({ idField: 'custom_doc_id' }).subscribe(snapshot => {
console.log(snapshot) // { custom_doc_id: 'bad_document_ref' }
});
I would like for the two above examples to return the same thing. I can do this by adding a pipe:
this.afs.doc('bad_document_ref').valueChanges({ idField: 'custom_doc_id' })
.pipe(map(snapshot => {
if(!snapshot) return undefined;
if (Object.keys(snapshot).length === 1 && Object.keys(snapshot)[0] === 'custom_id_field') {
return undefined;
}
return snapshot;
}))
.subscribe(snapshot => {
console.log(snapshot) // undefined
});
Is there a reason why the first two examples don't return the same thing? It seems like the logical thing to do, for the sake of consistency. Maybe there is a reason I'm not thinking of for why they would return different values?
The valueChange() method is basically the current state of your collection. You can listen for changes on the collection’s documents by calling valueChanges() on the collection reference. It returns an Observable of data as a synchronized array of JSON objects. All Snapshot metadata is stripped and just the document data is included.
When you pass an option object with an idField key containing a string like .valueChanges({ idField: 'propertyId' }); , it returns JSON objects with their document ID mapped to a property with the name provided by idField.
When the document doesn't actually exist, you would expect it to return nothing. In the first piece of code, you are not providing idField and the document doesn't exist, the observable returned undefined, which is justified. However, when you specify idField in the second piece of code, you basically say that when you return the data, you want the id of the document to be added to it. However if there is no data, there should not be any value returned, which is what you wanted to point out and which is quite justified. In other words, if the document does not exist, ideally it should return undefined even if you specify the idField parameter.
A GitHub link pointing towards the same issue says that the appropriate behavior is addressed in version 7 api.
Another GitHub link to be followed on this.
I am using:
angularFirestore.collection<Item>('items');
Note that for the object mapped I use <Item>, so maybe you can use it in your doc.

Model.find() returnes an object or array of objects? [mongodb]

const tours = await Tour.find()
when i use console.log(typeof tours) it shows object in console log.
but when i use console.log(tours) it shows an array of objects.
so i'm bit confused about what it actually returns back?
In JavaScript the value of typeof when used on an array is "object". The correct way to check if a variable is an array is Array.isArray() - it will return true or false depending if the argument passed is an array.

unable to fetch data from mongodb

Am working on nestjs and i want to fetch data from the collection on the basis of 'name' value.But i got output like this:
code of services:
async find_one(name):Promise<Usersinterface>{
const data=this.usersmodel.find(name).exec()
return data;
}
code of controller:
#Get('getitem')
async getitem(#Body()name):Promise<any>{
return this.usersService.find_one(name)
}
you should pass an object as a filter to the find method
so in the service, the query should look something like
find({ name: name })
the key (the first name) is the name of the property in your collection
the value (the second name) is the value you passed to the function
async find_one(name):Promise<Usersinterface> {
const data = this.usersmodel.find({ name: name }).exec()
return data;
}
hope it helps

Add snapshot items to array without looping or forEach

Using Firestore, I can assign items to an array with the following:
this.Svc.getCategories().valueChanges().subscribe(categories => {
this.categories = categories;
})
However, this listens for changes on the items and would add them to the array on a change.
Using
this.Svc.getCategories().get().subscribe(categories => {
categories.forEach(category => {
this.categories.push(category.data())
});
})
allows me to add the items to an array without listening for changes.
However, this method required me to either use forEach or a loop to push the data into the array.
Is there a way to get a one-time snapshot of the data and assign the data to an array without looping and using push()?
Check out the Firestore docs for reading data once https://firebase.google.com/docs/firestore/query-data/get-data

Create an object from multiple database collections (SailsJS, MongoDB, WaterlineJS)

I'm very new to Sails and noSQL databases and I'm having trouble gathering information together from different collections. Basically I need to gather an object of items from one collection and then use a foreign key stored in that collection to add data from a separate collection so the whole thing can be sent as one object.
Currently I find all the items in a collection called Artwork, then I'm using a for loop to iterate through the artworks. I need to use an id stored in Artworks to query a collection called Contacts but having successfully found the contact I am unable to pass it back out of the function to add it to the Artwork object.
find: function ( req, res, next ) {
Artwork.find().done( function ( err, artwork ) {
// Error handling
if (err) {
return console.log(err);
} else {
for ( x in artwork ) {
var y = artwork[x]['artistID'];
// Get the artsists name
Contact.find(y).done( function( err, contact ) {
// Error handling
if ( err ) {
return console.log(err);
// The Artist was found successfully!
} else {
var artist = contact[0]['fullName'];
}
});
artwork[x]['artistsName'] = artist;
}
res.send(artwork);
}
});
}
The result of the above code is an error thrown that tells me 'artist' is undefined. The variable is not being passed outside the function?
Any advice greatly received.
Sails is about to release an update that will include associations. In the meantime, here's an answer for how you can accomplish it using async. https://stackoverflow.com/a/20050821/1262998