Exception while invoking method 'customers.remove' Error: Match error: Expected string, got object

I have got the error when I’m trying to remove the Document from Customers Collection.
Then I’ve got the error below:

Exception while invoking method ‘customers.remove’ Error: Match error: Expected string, got object

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import { Table, Alert, Button } from 'react-bootstrap';
import { Meteor } from 'meteor/meteor';
import { createContainer } from 'meteor/react-meteor-data';
import { Customers } from '../../api/customers';

const handleRemove = (customerId) => {
  if (confirm('Are you sure? This is permanent!')) {
    Meteor.call('customers.remove', customerId, (error) => {
      if (error) {
        console.log('danger');
      } else {
        console.log('success');
      }
    });
  }
};

const STCustomers = ({ customers, match, history }) => (
  	<div className="Customers">
    	<div className="page-header clearfix">
      		<h4 className="pull-left">Customers</h4>
      		<Link className="btn btn-success pull-right" to={`${match.url}/new`}>Add Customer</Link>
    	</div>
    	{customers.length ? <Table responsive>
      	<thead>
        	<tr>
          		<th>Customer ID</th>
          		<th>First Name</th>
          		<th>Last Name</th>
          		<th />
          		<th />
        	</tr>
      	</thead>
      	<tbody>
        	{customers.map(({ _id, custId, firstname, lastname }) => (
          	<tr key={_id}>
            	<td>{custId}</td>
            	<td>{firstname}</td>
            	<td>{lastname}</td>
            	<td>
              		<Button
                		bsStyle="primary"
                		onClick={() => history.push(`${match.url}/${_id}`)}
                		block
              		>View</Button>
            	</td>
            	<td>
              		<Button
                		bsStyle="danger"
                		onClick={() => handleRemove(_id)}
                		block
              			>Delete</Button>
            	</td>
          	</tr>
        	))}
      	</tbody>
    	</Table> : <Alert bsStyle="warning">No customers yet!</Alert>}
  	</div>
);


STCustomers.propTypes = {
  customers: PropTypes.arrayOf(PropTypes.object).isRequired,
  match: PropTypes.object.isRequired,
  history: PropTypes.object.isRequired,
};

export default createContainer(() => {
  const subscription = Meteor.subscribe('customers');
  return {
    loading: !subscription.ready(),
    customers: Customers.find({}).fetch(),
  };
}, STCustomers);

imports/api/customers.js

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

export const Customers = new Mongo.Collection('customers');

Meteor.methods({
	'customers.insert': function customersInsert(cust) {
		check(cust, {
			custId: String,
			firstname: String,
			lastname: String,
			phoneno: String,
			email: String,
			address: String,
		});
		
		try {
			return Customers.insert({ owner: this.userId, ...cust });
		} catch (exception) {
			throw new Meteor.Error('500', exception);
		}
	},
	'customers.update': function customersUpdate(cust) {
		check(cust, {
			_id: String,
			custId: String,
			firstname: String,
			lastname: String,
			phoneno: String,
			email: String,
			address: String,
		});
		
		try {
			const customerId = cust._id;
			Customers.update(customerId, { $set: cust });
			return customerId;
		} catch (exception) {
			throw new Meteor.Error('500', exception);
		}
	},
	'customers.remove': function customersRemove(customerId) {
		check(customerId, String);

		try {
			return Customers.remove(customerId);
		} catch (exception) {
			throw new Meteor.Error('500', exception);
		}
	},
});

Please help to fix this error…

If I remove “check(customerId, String);” from 'cusetomers.remove’
I can remove the Document from Collection without any error.
So how should I implement this solution?

In your ‘customers.remove’ method, I would suggest logging the customerId argument. The problem is that it looks like customerId is coming in as an object.

1 Like

Thanks vigorwebsolutions,
If I found that it is object, how can I change it to string?
Or there is something wrong in other part?

I’m not sure about the syntax of your onClick={() => handleRemove(_id)}? Should the _id be wrapped in brackets?

As you suggest.
I have tried onClick={() => handleRemove({_id}) but it still send as object.
Is this right? Maybe I’m wrong.

Actually, I see some examples use the syntax like this, but they don’t have any problem but I have it.

Did you try logging the customerId in your method? Did it appear as an object?

Do you mean using “console.log(customerId);” in ‘customers.remove’ ?
I have done this but no console.log output.
Please suggest, if I’m wrong.

Actually, I see this “MongoID.ObjectID {_str: "5979495130644cd7680096d5"}” from the console.log

and in the Meteor Log

I20170727-09:54:33.824(7)? { [String: '5979495130644cd7680096d5'] _str: '5979495130644cd7680096d5' }
I20170727-09:54:33.898(7)? Exception while invoking method 'customers.remove' Error: Match error: Expected string, got object
I20170727-09:54:33.900(7)?     at exports.check (packages/check.js:56:15)
I20170727-09:54:33.901(7)?     at [object Object].customersRemove (imports/api/customers.js:46:3)
I20170727-09:54:33.902(7)?     at maybeAuditArgumentChecks (packages/ddp-server/livedata_server.js:1768:12)
I20170727-09:54:33.906(7)?     at packages/ddp-server/livedata_server.js:719:19
I20170727-09:54:33.908(7)?     at [object Object]._.extend.withValue (packages/meteor.js:1126:17)
I20170727-09:54:33.909(7)?     at packages/ddp-server/livedata_server.js:717:46
I20170727-09:54:33.911(7)?     at [object Object]._.extend.withValue (packages/meteor.js:1126:17)
I20170727-09:54:33.912(7)?     at packages/ddp-server/livedata_server.js:715:46
I20170727-09:54:33.913(7)?     at [object Object]._.extend.protocol_handlers.method (packages/ddp-server/livedata_server.js:689:23)
I20170727-09:54:33.914(7)?     at packages/ddp-server/livedata_server.js:559:43
I20170727-09:54:33.916(7)? Sanitized and reported to the client as: Match failed [400]

I run "meteor debug"
and add “console.log(customerId);”

	'customers.remove': function customersRemove(customerId) {
		console.log(customerId);
		check(customerId, String);		

		try {
			return Customers.remove(customerId);
		} catch (exception) {
			throw new Meteor.Error('500', exception);
		}
	},

also the debugging


 Object
    _str: "5979495130644cd7680096d5"
    __proto__: Object
   clone: function () {
   constructor: function (hexString) {
   equals: function (other) {
   getTimestamp: function () {
   toHexString: function () { 
   return this._str; }toJSONValue: function () { 
   return this._str; }toString: function () {
   typeName: function () {
   valueOf: function () { return this._str; }
   __proto__: Object
packages/meteor.js:946 Exception while invoking method 'customers.remove' Error: Match error: Expected string, got object
    at exports.check (packages/check.js:56:15)
    at [object Object].customersRemove (imports/api/customers.js:46:3)
    at meteorInstall.node_modules.meteor.ddp-server.livedata_server.js.maybeAuditArgumentChecks (packages/ddp-server/livedata_server.js:1768:12)
    at packages/ddp-server/livedata_server.js:719:19
    at [object Object]._.extend.withValue (packages/meteor.js:1126:17)
    at packages/ddp-server/livedata_server.js:717:46
    at [object Object]._.extend.withValue (packages/meteor.js:1126:17)
    at packages/ddp-server/livedata_server.js:715:46
    at [object Object].meteorInstall.node_modules.meteor.ddp-server.livedata_server.js._.extend.protocol_handlers.method (packages/ddp-server/livedata_server.js:689:23)
    at packages/ddp-server/livedata_server.js:559:43
packages/meteor.js:946 Sanitized and reported to the client as: Match failed [400]

By default, Meteor creates MongoDB ids as strings. However, MongoDB (and many libraries) create MongoDB ids as objects. It looks like these documents may have come from a source other than Meteor.

You could just accept these objects and use check(customerId, Object), which it sounds like will leave you with collections having mixed strings and objects for ids. Alternatively, you may want to consider using objects throughout by means of the idGeneration property on collections:

2 Likes

Thank you very much, robfallows.

I’ve got another error.

I20170728-10:18:49.915(7)? Exception while invoking method 'customers.remove' Error: Match error: Expected plain object
I20170728-10:18:49.922(7)?     at exports.check (packages/check.js:56:15)
I20170728-10:18:49.924(7)?     at [object Object].customerRemove (imports/api/customers.js:45:3)
I20170728-10:18:49.925(7)?     at maybeAuditArgumentChecks (packages/ddp-server/livedata_server.js:1768:12)
I20170728-10:18:49.927(7)?     at packages/ddp-server/livedata_server.js:719:19
I20170728-10:18:49.928(7)?     at [object Object]._.extend.withValue (packages/meteor.js:1126:17)
I20170728-10:18:49.930(7)?     at packages/ddp-server/livedata_server.js:717:46
I20170728-10:18:49.932(7)?     at [object Object]._.extend.withValue (packages/meteor.js:1126:17)
I20170728-10:18:49.934(7)?     at packages/ddp-server/livedata_server.js:715:46
I20170728-10:18:49.936(7)?     at [object Object]._.extend.protocol_handlers.method (packages/ddp-server/livedata_server.js:689:23)
I20170728-10:18:49.937(7)?     at packages/ddp-server/livedata_server.js:559:43
I20170728-10:18:49.940(7)? Sanitized and reported to the client as: Match failed [400]
I20170728-10:18:49.942(7)?

My bad for being lazy. Use check(customerId, Mongo.ObjectID);

1 Like

Thank you very much, It’s work !!! So great !!!

1 Like