NodeJS + Mongo - how to get the contents of collection? - json

I'm writing a simple NodeJS app with mongo. For connecting to mongo I use:
var mongo = require('mongodb'),
Server = mongo.Server,
Db = mongo.Db,
ObjectID = require('mongodb').ObjectID;
db.open(function(err,db) {...};
So, I have database "docs", and I've created a collection called "companies". Now it has 4 objects (records) in it. I want to get the full contents of this collection as an array and show them line-by-line:
//get companies list
app.get('/companies',function(req,res){
db.collection("companies",function(err,collection){
collection.find({},function(err, companies) {
companies.forEach(function(err,company){
console.log (company);
}
);
});
});
});
However, Node returns me such error:
TypeError: Object #<Cursor> has no method 'forEach'
Any ideas? Thanks in advance.

The companies parameter that's passed into your find callback is a Cursor object, not an array. Call toArray on it to convert the query results to an array of objects, or each to process the results one at a time.

use .each on companies, instead of forEach

Related

Parse a json object shows undefined

I was using OMDBapi to get the details of different movies. I successfully fetched the result and it returns a json object like this;
{"Title":"WWA: The Inception","Year":"2001","Rated":"N/A","Released":"26 Oct 2001","Runtime":"N/A","Genre":"Action, Sport","Director":"N/A","Writer":"Jeremy Borash","Actors":"Bret Hart, Jeff Jarrett, Brian James, David Heath","Plot":"N/A","Language":"English","Country":"Australia","Awards":"N/A","Poster":"https://m.media-amazon.com/images/M/MV5BNTEyNGJjMTMtZjZhZC00ODFkLWIyYzktN2JjMTcwMmY5MDJlXkEyXkFqcGdeQXVyNDkwMzY5NjQ#._V1_SX300.jpg","Ratings":[{"Source":"Internet Movie Database","Value":"6.0/10"}],"Metascore":"N/A","imdbRating":"6.0","imdbVotes":"22","imdbID":"tt0311992","Type":"movie","DVD":"N/A","BoxOffice":"N/A","Production":"N/A","Website":"N/A","Response":"True"}
Note that we get this type of object from the api if we want to get a particular movie details and that is what i was doing. Now to show the different details to a user, i started parsing this JSON object which works fine but when i try to get the value of the Value key present inside the Ratings key, it returns undefined.
I am working with react-native. After getting the data, i stored it inside the state, named it as details. Then to get it;
this.state.details.Title //if i wanted to get the Title and it works fine.
Then for Value inside Ratings;
this.state.details.Ratings[0].Value
But it returns undefined.
Also note that this works fine in pure Javascript as i parsed the dict in the browser console in the same way and it returned the correct value.
Here is more code;
componentDidMount() {
this.fetchData();
}
fetchData = async () => {
const response = await fetch(`http://www.omdbapi.com/?i=${this.props.navigation.getParam('i')}&apikey=******`) // where this.props.navigation.getParam('i') is the omdbid of the movie
const result = await response.json()
this.setState({details: result})
}
Here is error log;
undefined is not an object (evaluating 'this.state.details.Ratings[0]')
You're most likely trying to access state object before fetch has done it's job .... it's an async op ... so you should make sure your data is ready before rendering...
if (this.state.details) {
// start rendering...
}
More Explanation
your setState function should be executed right after fetch has finished its job, and since it's an async operation, it's going to take some time ...During that time, render function is executed with no state.details --> causing your issue ...
That's why you should check for state before rendering ... besides, the optional chaining trick Silversky Technology mentioned in his answer
If the value property you are accessing from the object might be not available for all the movies in the data you are getting from API response so it might cause you to error when accessing key from undefined objects.
To overcome the issue there is a way, you can try a fix as below:
this.state.details.Ratings[0]?.Value
The ? symbol lets the javascript not give an error when the value key not available in the object. it will make the accessing of property optional.
When storing objects in states it often causes problems as you are doing in line
this.setState({details: result})
Save result after strigifying it like
JSON.stringify(result)
this.setState({details: result})
Then when fetching form state, parse it back to object by
var result = JSON.parse(this.state.details)
Then you should be able to access it
You can access Ratings[0].Value by
this.state.details.Ratings && this.state.details.Ratings[0].Value
like,
<Text> {this.state.details.Ratings && this.state.details.Ratings[0].Value} </Text>

Create schemaless collection in mongoDB via mongoose

I have the following mongoose schema records:
var mongoose = require('mongoose');
module.exports = mongoose.model('lM', {
any : mongoose.Schema.Types.Mixed,
},'mlr');
And in my code I am doing as such:
var lm = require('../server/models/records');
new lm().save(lmr);
Being that lmr is a JSON object.
This produces a mongodb database with the name I provided but the records inside that collection contain only:
_id: objectID
_v: 0
The JSON objects is nowhere to be seen. How can I get the JSON object inside the any wrapper in the schema?
var lm = require('../server/models/records');
new lm({'any':lmr}).save();
In save() method pass callback function[optional] if you want to track error if any.
new lm({'any':lmr}).save(function(err){
if(err) {
console.log(err)
}else{
console.log('saved')
}
});
To create the schemaless collection you will have to set strict:false which is by default true. strict option ensures values passed to your model constructor that were not specified in schema do not get saved to the db.
strict option docs

Having trouble retrieving JSON from res

I'm using node, express, and mongoose.
I have a function that performs a search in a database and sends the response in a JSON format with:
res.jsonp(search_result);
This displays the correctly returned result in the browser as a JSON object. My question is, how do I get that JSON object?
I've tried returning search_result but that gives me null (possibly because asynchronous). I'd also like to not edit the current function (it was written by someone else). I'm calling the function and getting a screen full of JSON, which is what res.jsonp is supposed to do.
Thanks in advance.
Just make a new function that takes this JSON as parameter and place it inside the old one. Example:
// Old function
app.get('/', function(req,res){
// recieve json
json_object = .....
// Get json to your function
processJson(json_object);
// Old function stuff
.
.
.
});
function processJson(json_object) {
// Here you'll have the existing object and can process it
json_object...
}

Unable to get length of Firebase Objects

I am currently using AngularFire, and trying to get the length of objects in my database.
In my Firebase, the structure looks like
popping-fire-5575
celio
-JgaQt-tNq-gRVIVZdCD
artist:
track:
-JgaQuBoYk9VX3pWylx3
artist:
track:
-JgaQuf_pyBFJ7EA1Fo_
artist:
track:
In my controller,
var profileObject = FirebaseDemo.getBroadcast($routeParams.param);
var twotwo = profileObject.$asObject();
twotwo.$bindTo($scope, 'data');
When I console log the variable 'twotwo',
I get in return
Object
$$conf: Object
$id: "celio"
$priority: null
-JgaQt-tNq-gRVIVZdCD: Object
-JgaQuBoYk9VX3pWylx3: Object
-JgaQuf_pyBFJ7EA1Fo_: Object
__proto__: Object
However, I have tried all different ways to get the length, but I am not able to get to succeed. Could someone give me some directions or tips?
Firebase loads (and synchronizes) you data asynchronously, so by the time your console.log statement runs it is probably still busy loading the data.
Luckily AngularFire has a way to notify and run your code when the initial loading of data has completed:
var twotwo = profileObject.$asArray();
twotwo.$loaded().then(function(data) {
console.log('Initial data loaded', data.length);
});
The two main changes from your code:
Use $asArray() instead of $asObject(), since your data structure is an array
Listen for the $loaded "event" and respond to that
Note that AngularFire will already notify AngularJS of any changes to the data, so you won't have to respond to $loaded if you just bind the data to the $scope and show it in your view.

Am I using the wrong standard for JSON response?

I am new to Angular and I am trying to build a simple todo application using it. I have designed a module called TodoServices in which I am creating a User service using the factory method. The code looks something like:
angular.module('TodoServices', ["ngResource"])
.factory('User', function($resource){
return $resource('http://todoapi.rohanchhabra.in/users/:id');
});
The code in my app.js looks like:
var angularApp = angular.module('angularApp', ['TodoServices']);
angularApp.controller('UsersController', function(User){
this.users = {};
this.users = User.query();
});
When I run my application, I get this error: Error link
I think this is because my web service is returning an object which not only has the data but also has a few other things such as a status and messages. Now Is it a wrong way of doing it? Should I just return the array from the back end? What is the actual problem here and how to solve this?
As your error link says:
By default, all resource actions expect objects, except query which expects arrays.
You should use an other function like User.Get() when you're not expecting an array but just a single object.