CompoundJS: Populating database with seed file hangs - node.js

I'm trying to populate my CompoundJS application's Mongo database with seed files, but whenever I run compound seed, the terminal hangs after my console.log statements... the database fills, but I have to kill the command with Ctrl-c.
I've tried doing compound seed harvest, but that doesn't create proper seed files, so I've decided to make my own. Here is my respective code:
db/seeds/development/Host.js (seed file)
console.log("Seeding Hosts....");
var hosts = [
{
hid: '1',
name: 'MY API',
domain: 'mydomain.com'
}
];
hosts.forEach(function(obj, err){
Host.create(obj, function(err, host){
console.log('host Added: ', host);
});
});
db/schema.js
var Host = describe('Host', function () {
property('hid', String);
property('name', String);
property('domain', String);
set('restPath', pathTo.hosts);
});
config/database.js
module.exports = {
development: {
driver: 'mongodb',
url: 'mongodb://localhost/apicache-dev'
},
test: {
driver: 'mongodb',
url: 'mongodb://localhost/apicache-test'
},
production: {
driver: 'mongodb',
url: 'mongodb://localhost/apicache-production'
}
};
Like I said, when I run compound seed, it shows both console.log statements, and it puts my data into the database, but it just hangs... never actually returning to the command line, so I'm forced to kill it with Ctrl-c. I would like to solve this problem, as I have to automate this process, and it's a bit hard automating if it's just hanging. What am I doing wrong? Any help would be appreciated!
Cross-posted.
EDIT
So when I try to use the Coffee script version that's generated from compound seed harvest:
db/seeds/development/Host.coffee
Host.seed ->
hid: '1'
name: 'MY API'
domain: 'mydomain.com'
id: "52571edd2ac9056339000001"
I get the error collection name must be a String. So I was a little curious and went to where that error was being generated... in node_modules/jugglingdb-mongodb/node_modules/mongodb/lib/mongodb/collection.js on line 103. I put a console.log(collectionName) right before that if statement and saw an interesting output...
{ hid: '1',
name: 'MY API',
domain: 'mydomain.com',
id: NaN }
So clearly it's not a string, but a hash object, and my collection's name (Host) is nowhere in sight. Seems like a bug to me.

So I finally got it to work. Apparently, there was something wrong with the auto-genned id from the harvest command, so I ended up deleting that line, and voila! Planting the seeds works like a charm. I converted the rest of my JS files to Coffee script files and everything works. Sometimes you just need to have a conversation with yourself on the Internet...
Here's my seed file:
Host.seed ->
hid: '1'
name: 'MY API'
domain: 'mydomain.com'
And doing compound seed works without hanging and populates the database. Guess Coffee script is the way to go?

Related

Why is the JSON output different from the actual output as rendered in the browser? [duplicate]

I have a problem with logging out the contents of an array inside an object. The actual object looks like this
var stuff = { accepted: [ 'item1', 'item2' ],
rejected: [],
response: 'Foo',
envelope: { from: 'The sender', to: ['new item1', 'new item2'] },
messageId: 'xxxxxxxxxxxxx' } }
The console.log shows the items of the first array fine but the second array is being output as [Object].
{ accepted: [ 'item1', 'item2' ],
rejected: [],
response: 'Foo',
envelope: { from: 'The sender', to: [Object] },
messageId: 'xxxxxxxxxxxxx' } }
What is happening here and how can I get the items of the second array to show when I console.log. Thanks for any help!
UPDATE
Sorry, I forgot to add that I am working exclusively in Node.js so it's a server side log that needs to display the object exactly as it's received from a callback with a straight console.log, ie. no further stringify-ing.
I also just tried creating another random object with a similar structure like this.
var objText = {
fun: {
stuff: 'Some stuff',
list: ['this', 'it', 'takes']
}
};
The console.log for the above is:
{ fun: { stuff: 'Some stuff', list: [ 'this', 'it', 'takes' ] } }
This appears to be the same structure to me and yet the console.log works fine so it seems to be perfectly possible in Node to log arrays content even when it's embedded inside and an object inside an outer object.
It looks like this is an old topic, anyway
I've faced the same issue, embedded array printed as [Array].
It is because of console.log in the node.js uses util.inspect for print, the default depth is 2.
So, to print something which is deeper than 2 followings can be used:
const util = require('util')
console.log(util.inspect(errors, true, 10))
This is the default way for some browser and implementations of showing too complex or deep objects/arrays with console.log. An alternative is to use JSON.stringify with console.log:
var stuff = {
accepted: ['item1', 'item2'],
rejected: [],
response: 'Foo',
envelope: {
from: 'The sender',
to: ['new item1', 'new item2']
},
messageId: 'xxxxxxxxxxxxx'
}
console.log(JSON.stringify(stuff, null, 4));
EDIT:
Another alternative is to use console.dir in case you have a too complex or recursive object, see https://stackoverflow.com/a/27534731/6051261
Try it with: console.log(JSON.stringify(variable))
If you like Chrome devtools, that folds your json objects and let you observe a lot of things, you can use the --inspect flag:
node --inspect index.js
The console will then give you an URL and you just have to copy paste in Google Chrome to enjoy Google Chrome console.
More information on this link

Array showing as undefined, even though I am able to log it's contents

I am trying to get data from array, but when I try to get information from it, I am getting an error that shows the array is undefined. Please check the following code for a better explanation:
const socketInfo = CircularJSON.stringify(socket);
console.log(socketInfo); // shows full array correctly
console.log(socketInfo.server); // says undefined, even though server object has information in it
I mentioned in my comment that you have to iterate over the array. I do not know what "socketInfo" looks like, but if it is an array, you can do this to get the servers
var socketInfo = [
{
server: 'dev',
ip: '10.10.10.1'
},
{
server: 'staging',
ip: '10.10.10.2'
},
{
server: 'production',
ip: '10.10.10.3'
}
];
socketInfo.forEach(function(x) {
console.log(x.server);
});
I was able to get array values after I added a JSON.parse and toString() ....
const socketInfo = JSON.parse(CircularJSON.stringify(socket).toString());

aws-sdk javascript filter on tag:key=value

Folks,
I am having difficult time understanding the docs http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/frames.html
I need to grab all the running instances with the following tags assigned to them:
project=foo
environment=production
The following does not seem to work.
var params = {
DryRun: false,
Filters: [
{
Name: 'instance-state-name',
Values: [
'running'
],
},
{
Name: 'tag:key=value',
Values: [
'foo',
'production'
],
},
]
};
ec2.describeInstances(params, function (err, data) {
...
If your tag's key is 'foo' and its value is 'production', you should change your code to the following. The Name is in the 'tag:key' format, and the Values are the data you are looking for that correspond to that key.
{
Name: 'tag:foo',
Values: [
'production'
],
},
This is slightly related, and may help anyone who found there way here like I did.
I was trying check if an Instance with a tag Name=myInstance, was running in my aws account.
It's pretty difficult to check existence of resources in aws, but clairestreb's answer led me to the work around for this case.
I've begun developing a library of other such work arounds, and with it you can now do this:
Find Running Instance with tag Name=myInstance
var ex = require('aws-existence')
var ec2 = ex.ec2({region: 'us-west-2'})
ec2.doesInstanceExist('myInstance', 'running')
.then(doSomething)
function doSomething (exists) {
if (exists) {
// stop it?
} else {
// start it?
}
}
So that's doesInstanceExist(identifier, instanceState) where the identifier is a name tag, or an InstanceId. And state is optionally any one of the instance-state-name values. If you omit the state, it will tell you if an instance in any of the states exists.
You can find the library here:
nackjicholson/aws-existence

Error: text search not enabled:- in mongodb

I get the following error :-
[Error: text search not enabled]
I am running the folliowing function which is essentially a mongoose-mongodb operation.
var textSearch = require('mongoose-text-search');
exports.dbTextSearch = function () {
console.log('dbTextSearch');
var gameSchema = mongoose.Schema({
name: String
, tags: [String]
, likes: Number
, created: Date
});
gameSchema.plugin(textSearch);
gameSchema.index({ tags: 'text' });
var Game = mongoose.model('Game', gameSchema);
Game.create({ name: 'Super Mario 64', tags: ['nintendo', 'mario', '3d'] }, function (err) {
Game.textSearch('3d', function (err, output) {
if (err) return console.log(err); // this outputs the error.
var inspect = require('util').inspect;
console.log(inspect(output, { depth: null }));
});
});
}
I am trying to implement the mongoose-text-search plugin
In MongoDB 2.4 - to enable the experimental text search, use
setParameter=textSearchEnabled=true
The following line didn't work for me in the mongodb.conf file.
textSearchEnabled=true
EDIT In MongoDB 2.6 + it is enabled by default. You just need to set up your text indexes.
MongoDB Text search is still an experimental feature. That's why it is disabled by default and must be enabled manually. You can do so by either starting mongod with the command line parameter --setParameter textSearchEnabled=true or adding the line textSearchEnabled=true to the file mongodb.conf.
Please note that as an experimental feature, text search should not be used in a production environment yet.
UPDATE
As of version 2.6 of mongoDB text search feature has production-quality and is enabled automatically.
You have to specify this startup parameter (mentioned in above answers) when you start mongo. So if you start manually, then use:
mongod --setParameter textSearchEnabled=true
Otherwise, if mongo is deamonized, put it into deamon script. Something like this:
start()
{
echo -n $"Starting mongod: "
daemon --user "$MONGO_USER" $NUMACTL $mongod --setParameter textSearchEnabled=true $OPTIONS
Then you create text index and check it's existence:
db.mycoll.createIndex( { someFieldName: "text" } );
db.mycoll.getIndexes()

Fetch Backbone collection with search parameters

I'd like to implement a search page using Backbone.js. The search parameters are taken from a simple form, and the server knows to parse the query parameters and return a json array of the results. My model looks like this, more or less:
App.Models.SearchResult = Backbone.Model.extend({
urlRoot: '/search'
});
App.Collections.SearchResults = Backbone.Collection.extend({
model: App.Models.SearchResult
});
var results = new App.Collections.SearchResults();
I'd like that every time I perform results.fetch(), the contents of the search form will also be serialized with the GET request. Is there a simple way to add this, or am I doing it the wrong way and should probably be handcoding the request and creating the collection from the returned results:
$.getJSON('/search', { /* search params */ }, function(resp){
// resp is a list of JSON data [ { id: .., name: .. }, { id: .., name: .. }, .... ]
var results = new App.Collections.SearchResults(resp);
// update views, etc.
});
Thoughts?
Backbone.js fetch with parameters answers most of your questions, but I put some here as well.
Add the data parameter to your fetch call, example:
var search_params = {
'key1': 'value1',
'key2': 'value2',
'key3': 'value3',
...
'keyN': 'valueN',
};
App.Collections.SearchResults.fetch({data: $.param(search_params)});
Now your call url has added parameters which you can parse on the server side.
Attention: code simplified and not tested
I think you should split the functionality:
The Search Model
It is a proper resource in your server side. The only action allowed is CREATE.
var Search = Backbone.Model.extend({
url: "/search",
initialize: function(){
this.results = new Results( this.get( "results" ) );
this.trigger( "search:ready", this );
}
});
The Results Collection
It is just in charge of collecting the list of Result models
var Results = Backbone.Collection.extend({
model: Result
});
The Search Form
You see that this View is making the intelligent job, listening to the form.submit, creating a new Search object and sending it to the server to be created. This created mission doesn't mean the Search has to be stored in database, this is the normal creation behavior, but it does not always need to be this way. In our case create a Search means to search the DB looking for the concrete registers.
var SearchView = Backbone.View.extend({
events: {
"submit form" : "createSearch"
},
createSearch: function(){
// You can use things like this
// http://stackoverflow.com/questions/1184624/convert-form-data-to-js-object-with-jquery
// to authomat this process
var search = new Search({
field_1: this.$el.find( "input.field_1" ).val(),
field_2: this.$el.find( "input.field_2" ).val(),
});
// You can listen to the "search:ready" event
search.on( "search:ready", this.renderResults, this )
// this is when a POST request is sent to the server
// to the URL `/search` with all the search information packaged
search.save();
},
renderResults: function( search ){
// use search.results to render the results on your own way
}
});
I think this kind of solution is very clean, elegant, intuitive and very extensible.
Found a very simple solution - override the url() function in the collection:
App.Collections.SearchResults = Backbone.Collection.extend({
urlRoot: '/search',
url: function() {
// send the url along with the serialized query params
return this.urlRoot + "?" + $("#search-form").formSerialize();
}
});
Hopefully this doesn't horrify anyone who has a bit more Backbone / Javascript skills than myself.
It seems the current version of Backbone (or maybe jQuery) automatically stringifies the data value, so there is no need to call $.param anymore.
The following lines produce the same result:
collection.fetch({data: {filter:'abc', page:1}});
collection.fetch({data: $.param({filter:'abc', page:1})});
The querystring will be filter=abc&page=1.
EDIT: This should have been a comment, rather than answer.

Resources