Eduardo C. K. Ferreira
Eduardo C. K. Ferreira

Reputation: 374

How to insert N elements to a Document in Mongo using Meteor

I am trying the past 3 days to do it and could not succeed yet. I have the following code, that adds a Book do a Books colection on a MongoDB. The App is build with meteor:

    //save authors book information
    //as a book can have N authors, this loop get all input fields with authors

    var authors = [];
    $('.author-field').each(function(){
        authors.push[{
            'author': $(this).val()
        }]
    });

    //save static book information
    var book = {
        title: $(e.target).find('[name=add-title]').val(),
        (...)
        language: $(e.target).find('[name=add-language]').val(),
        authors: authors //add all authors here
    }

    Meteor.call('bookInsert', book, authors, areas, function(error, result) {
        if(error)
            return throwError(error.reason);
        Router.go('/');
    });

And I always get an error. Now I am getting this:

errorClass {message: "Match error: Unknown key in field authors", path: "authors", sanitizedError: errorClass, errorType: "Match.Error", stack: (...)…}

Other times, with few changes, I has getting: was expecting an object and got an array or something like that. What am I doing wrong here?

-- Update --

The code that actually add to db is this one:

    //meteor methods
Meteor.methods({
  bookInsert: function(postAttributes, authors, areas) {
    check(Meteor.userId(), String);
    check(postAttributes, {
        title: String,
        (...)
        language: String,
        authors: Object
    });
    var user = Meteor.user();
    //_.extend comes from Underscore library
    var book = _.extend(postAttributes, { 
        userId: user._id,
        author: user.username,
        submitted: new Date()
    });
    var bookId = Books.insert(book);


    return {
        _id: bookId
    }
}
})

Upvotes: 0

Views: 496

Answers (2)

tomsp
tomsp

Reputation: 1807

there are a couple of things that you can do.

First, to get the author data into your array you need to change the brackets of the push function from [ to (:

var authors = [];
$('.author-field').each(function(){
    authors.push({
        'author': $(this).val()
    })
});

console.log( authors ) afterwards to confirm that it worked.

Second, you need to check against an array of objects as @EduardoC.K.Ferreira suggested. so your check function should look like this

check(postAttributes, {
    title: String,
    (...)
    language: String,
    authors: [Object]
});

that should get it going. however, there are two more things i noticed:

  1. why do you pass three arguments in your call Meteor.call('bookInsert', book, authors, areas, ... but you don't use them. Plus, the authors array is contained within the book object, so why pass it again separately?

  2. i assume you want to confirm that a user is logged in here: check(Meteor.userId(), String);. you should use the the this.userId object in method calls (see here) and check that it is not null, i.e. user is logged in

like so:

if (! this.userId)
  throw new Meteor.Error(401, "You must be logged in!");

Finally, be sure that user.username exists before you use it. hope that helps.

Upvotes: 2

bigmadwolf
bigmadwolf

Reputation: 3519

It looks to me like you've specified the authors field check incorrectly, you have it matching an object where it looks like it should be an Array.

Try changing the following in your method to see if you're able to save :

check(postAttributes, {
    title: String,
    (...)
    language: String,
    authors: Any
});

If I understand the documentation correctly, it looks like you'll need to check for an array of objects with something like [Object].

Upvotes: 0

Related Questions