1

I am having trouble trying to get a Collection.upsert to work in Meteor 1.4.3.2.

My app pulls in active listings from eBay and inserts them into the database if they don't already exist, otherwise it updates the listing that is already stored. So, what I am trying is the following in a meteor method:

let upsertObj = {$set: {}};

const account = ListingAccounts.findOne( ... );

if (!account) // throw an error because account info is required by schema

upsertObj.$set['account.id'] = account._id;
upsertObj.$set['account.username'] = account.username;
upsertObj.$set['account.nickname'] = account.nickname;

// ... also gets other listing data such as listingId, title, condition, etc...

return Listings.upsert({listingId: eBayListingID}, upsertObj);

There are other values that are nested similarly to the account details above, and they all seem to work. I've logged the final upsertObj object and the values are valid and comply with my schema (SimpleSchema), but just for good measure, here is an excerpt of the final upsert object I am logging on the server just before the upsert happens:

{ '$set': 
    { 'account.id': 'trustmethisisvalidstring',
      'account.username': 'ValidAccountNameString',
      'account.nickname': 'ValidAccountNicknameString',
      /* more name:values below this */
    }
}

Here is an excerpt from my schema (aldeed:simple-schema 1.5.3)

ListingsSchema = new SimpleSchema({
    account: {
        type: Object
    },
    "account.id": {
        type: String,
        optional: true // added after question asked
    },
    "account.username": {
        type: String,
        optional: true // added after question asked
    },
    "account.nickname": {
        type: String,
        optional: true // was always optional
    },
    ...
});

I am receiving the error on the client with the following details: [{"name":"account.id","type":"required","value":null},{"name":"account.username","type":"required","value":null}]

with the reason reason: "Id is required"

This is the first time I've tried using upsert and I can't help but feel I am missing the mark on something. Maybe my syntax is off, or maybe I'm just not using bracket notation correctly? I don't know, the Meteor docs unfortunately do not have any examples that I could find.

Any assistance or clarification on using Upsert would be super appreciated, thank you!

Ticdoc
  • 248
  • 3
  • 15
  • I made a small change to my schema, and made the erroring values `optional: true`, and that seemed to fix things, and the values were definitely not `null` like the error I was receiving states. As of right now the code is "working", but I don't believe that making the value in the schema optional would be an acceptable fix. Still not sure what's happening wrong here. I am using SimpleSchema. – Ticdoc Feb 27 '19 at 20:16
  • 1
    Use [Clean](https://github.com/aldeed/simple-schema-js#cleaning-objects) to validate the object before upsert to see what's causing the errors. Also, may be the record is not present in the DB and in your schema you made the `_id` field as required? Can you add your schema to the question? Thank you. – Sudheer Jami Feb 28 '19 at 06:10
  • @SudheerJami Thanks for the reply, I just added an excerpt from the schema including version. I was under the assumption that `_id` came with mongodb inserts by default, I have never had to require it. Currently, the upsert is working as intended with the optional fields set to true on the two values that were erroring: It is inserting when it does not exist, and updating when it does exist. – Ticdoc Feb 28 '19 at 19:11
  • 1
    The schema looks fine to me. I asked you to check for the `_id` as the error looks similar from [here](https://www.bountysource.com/issues/4799633-id-is-required-validation-error-thrown-when-_id-is-defined-in-schema). Could be that the `_id` of `account` that you are passing to the field `account.id` is an object? Since the default `_id` that meteor create looks something like `ObjectId("5c423d..75")` instead of something like `"5c423d..75"`. – Sudheer Jami Mar 01 '19 at 03:27
  • According to the meteor docs for version 1.4 (https://docs.meteor.com/v1.4/api/collections.html#Mongo-Collection) the `_id` is by default a `'STRING'`, I have not set up any of my collections to use `'Mongo.ObjectID'`. – Ticdoc Mar 01 '19 at 15:36
  • 1
    did you try using [$setOnInsert](https://docs.mongodb.com/manual/reference/operator/update/setOnInsert/) ? – Gonsalo Sousa Mar 14 '19 at 22:09
  • @GonsaloSousa I actually did not, thanks for pointing this out to me, this is an interesting thing I will look into. – Ticdoc Mar 15 '19 at 19:43

0 Answers0