Save records into the same collection in Mongo DB using Meteor js

144 Views Asked by At

Being new to Meteor JS, I'm confused on how to update a record. I have 2 templates AddSchoolLayout and Schoolcontactlayout, AddSchoollayout creates the record in Mongo db, now, for the same school I want to add its address still on the same DB NewSchoolDB but as I tried this I keep getting the error below about wrong ID. What wrong am I to right?

Note that my language might not correlate with Mongo's; I'm still fresh, coming from the SQL background.

This is the method.js where the record is been saved.

//methods.js
    if (Meteor.isServer) {
        Meteor.methods({
            SchoolRegister: function (phone, schoolemail) {
                if (!Meteor.userId()) {
                    throw new Meteor.error('Not authorized');
                    return false;
                }else{

                    NewSchoolDB.insert({
                        authorId: Meteor.userId(),
                        phone: phone,
                        schoolemail
                    });
                }
            }
        });
    }

This is the event for saving a new school

//add school
Template.AddSchoolLayout.events({
    'submit .addnewschool': function (event, template) {
        event.preventDefault();

        var newschoolname = trimInput(event.target.newschoolname.value);

        if (isNotEmpty(newschoolname)) {

            Meteor.call('SchoolRegister', newschoolname,
                function (error, response) {
                    if (error) {
                        Bert.alert(error.reason, 'danger', 'growl-top-right');
                        return false;
                    }else{
                        Bert.alert("School successfully created", "success", "growl-top-right");
                        FlowRouter.redirect('/schoolcontact');
                    }
                });

        }
        return false;
    }
});

This is where I want to update the school address

//school contact
Template.SchoolContactLayout.events({
    'submit .contactschool': function (event) {
        event.preventDefault();

        var phone = trimInput(event.target.phone.value);    
        if (isNotEmpty(phone)) {
            Meteor.call('SchoolRegister', phone, function (error, response) {
                if (error) {
                    Bert.alert(error.reason, 'danger', 'growl-top-right');
                    return false;
                }else{
                    Bert.alert('School address updated successfully', 'success', 'growl-top-right');
                    FlowRouter.redirect('/logo-upload');
                }
            });
        }
        return false;
    }
});

Error logged on the console

I20170524-17:44:14.051(1)?     at packages/ddp-server/livedata_server.js:559:43
I20170524-17:51:54.678(1)? Exception from sub NewSchoolDB id onFTu2j3xRmbqC5WF TypeError: this.userId is not a function
I20170524-17:51:54.710(1)?     at [object Object]._handler (lib/pulbish/published.js:3:13)
I20170524-17:51:54.712(1)?     at maybeAuditArgumentChecks (packages/ddp-server/livedata_server.js:1737:12)
I20170524-17:51:54.713(1)?     at [object Object]._.extend._runHandler (packages/ddp-server/livedata_server.js:1035:17)
I20170524-17:51:54.714(1)?     at [object Object]._.extend._startSubscription (packages/ddp-server/livedata_server.js:853:9)
I20170524-17:51:54.715(1)?     at [object Object]._.extend.protocol_handlers.sub (packages/ddp-server/livedata_server.js:625:12)
I20170524-17:51:54.719(1)?     at packages/ddp-server/livedata_server.js:559:43
1

There are 1 best solutions below

9
On BEST ANSWER

Your SchoolRegister method accepts 2 arguments: phone and schoolmail. When you create the school you call the methods with one argument called newschoolname. So something is wrong here with your naming convention, but it shouldn't really matter regarding your question.

With MongoDB, you use insert to add a new record to your collection. If you need to update it, use update. So one way to solve your problem is to:

  • In AddSchoolLayout, call your method to insert the document the first time. NewSchoolDB.insert(...) will return the ID of the created record. Keep that ID and pass it to your next page, for exemple in the URL.
  • In your next page, SchoolContactLayout, you need to call a new method which is going to update your school, using the ID returned by the previous method. This new method will look something like this:

    SchoolUpdate: function (schoolId, phone) {
        if (!Meteor.userId()) {
            throw new Meteor.error('Not authorized');
            return false;
        }else{
            NewSchoolDB.update(schoolId, { $set: { phone } });
        }
    }
    

The first argument of the update MongoDB function is the ID of the record you want to update. The second arguments are the modifiers you want to use to update your record. Here is the full list of modifier you can use: update modifiers

EDIT: how to pass ID from one layout to another:

I didn't use FlowRouter for a while and I can't test it right now so you may have to do some correction, but here is how I would do it to give you an idea:

First you need to define your route SchoolContactLayout with something like this:

FlowRouter.route('/schoolcontact/:schoolId', {
  name: 'schoolContact',
});

This adds a schoolId parameter to the route.

In your SchoolRegister method, get the return ID and return it:

var id = NewSchoolDB.insert({
  authorId: Meteor.userId(),
  schooleName
});
return { id }

Edit your redirection FlowRouter.redirect('/schoolcontact'); with FlowRouter.go('/schoolcontact/' + response.id);

You can then edit your contactSchool event with something like this:

Template.SchoolContactLayout.events({
  'submit .contactschool': function (event) {
     event.preventDefault();

     var schoolId = FlowRouter.getParam('schoolId');
     var phone = trimInput(event.target.phone.value);    
     if (isNotEmpty(phone)) {
       Meteor.call('SchoolUpdate', schoolId ,phone, function (error, response) {
         if (error) {
           Bert.alert(error.reason, 'danger', 'growl-top-right');
           return false;
         }else{
           Bert.alert('School address updated successfully', 'success', 
            'growl-top-right');
           FlowRouter.redirect('/logo-upload');
         }
       });
     }
     return false;
   }
 });

Notice the var schoolId = FlowRouter.getParam('schoolId'); to get the ID from URL parameter so I can use it in the update method.