Even though attribute is unique:true, could someone comment why upsert still creates new and duplicate row when userid and username (both are not unique) are modified?

in lib/collections.js:

Schemas.FutureTask = new SimpleSchema({
    number: {
        type: String,
        label: "TICKET_NUMBER",
        max: 10, //typically 10 digits
        index: true,
        unique: true
    },
     userid: {
        type: String,
        label: "USER_ID",
        max: 10 
    },
    username: {
        type: String,
        label: "ASSIGNED_TO",
        max: 50
    },

in server/main.js:

FutureTasks.upsert({
                    number: contentObj.records[i].number,
                    assignment_group: contentObj.records[i].assignment_group
                }, {
                    // Modifier
                    $set: {
                        userid: contentObj.records[i].assigned_to_userid,
                        username: contentObj.records[i].assigned_to,
                        start_date: myStartTime,
                        end_date: myModifiedEndTime
                    }
                }

I need to work with _id?

You are also using collection2 and have attached the schema to the collection?

Thanks Rob, yes I did. But I think I didn’t do meteor reset, now no duplicated rows as expected, but still getting:

Exception in callback of async function: Error: Future resolved more than once

Even though collection is updated correctly? Someone did mentioned setting flags but I just want to know why this is happening in the first place.

Hmm. No idea - sorry - a quick Google of that error explains how it occurs (Fiber.return called more than once), but unless you know which package is causing it, it’s not really going to help much!

Hi Rob

I think this exception came inside a for loop when I did a db.Collections.upsert with callback:

 for (var i = 0; i < recordsLength; i++) { 

 FutureTasks.upsert({
                    number: contentObj.records[i].number,
                    assignment_group: contentObj.records[i].assignment_group
                }, {
                    // Modifier
                    $set: {
                        start_date: modifiedStartTimeString,
                        end_date: modifiedEndTimeString
                    }
                }
               ,
              function (err, doc) {
                     if (err) {
                      console.log('error inside upsert : ', err.reason);
                        future.throw(err);
                  } else {
                      console.log('doc inside upsert : ', doc);
                      future.return(doc);
                   }
               }
            ); // End of insert
        } // End of 'ignore if null'
    } // End of for loop
   try {
             return future.wait();
        }
        catch (err) {
            throw new Meteor.Error("insert-error", err);
        }


   }

So how would one return a future inside a for loop? I guess we can’t do a for loop wrapping a function that returns s promise or future, but instead do something like promise.forEach etc?