Meteor.call can't see my function in collection.js

I just started learning meteor and this is my first web app. I’m following a tutorial from YouTube, which was created some years ago. I have completed my application, and everything worked just fine, until I started to make the application more secure by following best practices as advised on the official meteor site and by the video narrator. I’m going to outline the series of events that possibly led to the issue:

First let me explain my folder structure - I have three folders, client, server and lib. In my client folder, there is a main.js and main.html. In my server, there is a main.js, while in the lib folder, there is a collections.js.

The first thing I did was to uninstall the insecure package, and I got a notification that it was successful. Then I started to transfer the insert, remove operations (while including added entry checks) from client/main.js to lib/collections.js which is where I started getting the non-defined error in the console.

I believe it might be from the imports/exports but I have gone through it and can’t seem to know what’s wrong.

In my client/main.js I had these as imports:

 import { Template } from 'meteor/templating';
   import { Meteor } from 'meteor/meteor';
   import { Notes } from '../lib/collections.js';
   import { Accounts } from 'meteor/accounts-base';
   import './main.html';

In my server/main.js I had these as imports:

 import { Meteor } from 'meteor/meteor';
    export const Notes = new Mongo.Collection('notes');

In the lib/collections.js I had these as imports:

 import { Mongo } from 'meteor/mongo';
   import { Meteor } from 'meteor/meteor';
   import { check } from 'meteor/check';

   export const Notes = new Mongo.Collection('notes');

The function definition where the error is coming from is defined in collections.js in lib as:

Meteor.methods({
	   'notes.insert'(text) {
.
.
.
   'notes.remove'(note) {
        	check(note._id, String);
   	   Notes.remove(note._id);
      }
   });

The function was invoked like this in the client main.js:

Template.note.events ({
	   'click .delete-note': function(){
		   Meteor.call('note.remove', this);
	        	return false;

	   }
   });

The error is that note.remove function is not being called.

Please assist in knowing why note.remove is not being invoked.

It seems like a small misspell. You method is called notes.remove, but you call it as note.remove

1 Like

Thanks for spotting that. But unfortunately after fixing that it still returned this in the console when I try to remove an entry:

" isClientSafe: true, error: 404, reason: “Method ‘notes.remove’ not found”, details: undefined, message: “Method ‘notes.remove’ not found [404]”, errorType: “Meteor.Error” }"

Are you importing the collections.js file on your main? or anywhere else?

I dont see that on what you typed for server/main.js but I see it on you client/main.js. I think thats the reason

Try to format your code next time using putting it between backticks ```

2 Likes

If I understand you correctly you mean I should have

import { Notes } from '../lib/collections.js';

in my server/main.js, I just did that making it

import { Meteor } from 'meteor/meteor';
import { Notes } from '../lib/collections.js';
export const Notes = new Mongo.Collection('notes');

and client/main.js remains

import { Template } from 'meteor/templating';
import { Meteor } from 'meteor/meteor';
import { Notes } from '../lib/collections.js';
import { Accounts } from 'meteor/accounts-base';

import './main.html';

But unfortunately, adding that line gave an error of ‘While building for os.linux.x86_64:
server/main.js: /home/administrator/WebProjects/notemanager/server/main.js: Duplicate declaration “Notes”’ while on the console, the error is " The character encoding of the HTML document was not declared. The document will render with garbled text in some browser configurations if the document contains characters from outside the US-ASCII range. The character encoding of the page must be declared in the document or in the transfer protocol. localhost:3000".

When I remove export const Notes = new Mongo.Collection('notes'); to solve the duplication error, I get the errors "Exception while simulating the effect of invoking ‘notes.remove’ " "Error invoking Method ‘notes.remove’ " “isClientSafe: true, error: 400, reason: “Match failed”, details: undefined, message: “Match failed [400]”, errorType: “Meteor.Error” }”

I’m willing to make the entire files public, if there is a way that is possible. I really need to get this basic code to work, as it will provide me with the foundational knowledge on how meteor works in building bigger applications. I still think its an import issue but don’t seem to know where the mistake lies.

If you can post a link to a repo it will help.

In server Main you dont have to redeclare the Notes collection, its already declared on the collections.js file.

Now I think the issue is you are exporting just Notes by doing { Notes }. I will recommend using a different file structure. But just to solve this issue you should import collections.js like this in server/main.js

import '../lib/collections.js'

Tried using import '../lib/collections.js' didn’t work. I’ve created a repository on git. Thanks for the replies.

Check the pull request, you where almost there.

1 Like

You’re really close to getting it working!

In this error:

The key part is:

reason: “Match failed”

Match is part of the check package and so it’s saying that an error was thrown when calling

check(note._id, String);

in the notes.remove method.

So you need to check that the object being passed into the message is actually a note and has an _id property which is a string.

Easiest way to do that is to add a breakpoint on the client in dev tools. Because the method runs on both client and server, you can see what happens on the client and expect that the same is happening on the server

1 Like

Thanks for the replies, everything works well when I remove the check line of code. Since we are not getting it as an input, I don’t even think that specific check is necessary because its generated by the system not the user. When I tried to get the data type of note._id it returned an object. Also thanks for letting me know about the debugger tool on my browser, I saw where the exception was being thrown.

This is the format of what is coming into the function:

Object { text: "Fifth entry added", createdAt: Date 2018-12-11T02:10:44.684Z, _id: {…} }

As a workaround to get it to work - I did this:
client/main.js

var thisnote=this._id;
String(thisnote);

Meteor.call('notes.remove', thisnote);
		return false;

Then in the collections.js:


'notes.remove' (thisnote) {
check(thisnote, String);
Notes.remove(thisnote);
   }