Auto increment a property value in Strongloop loopback model
Asked Answered
H

3

9

Is there a built-in way to auto increment a model's property value is Strongloop loopback ? This model has a property named orderNumber and I want it to start at 1 and increment by 1 every time a new model is created. This model is persisted to a mongo DB. If Strongloop loopback does not have a built in way, then what would be considered best practice using javaScript, Node and mongoDB ?

Thanks,

Huff answered 2/1, 2015 at 16:19 Comment(2)
docs.mongodb.org/manual/tutorial/…Loom
Thanks @Brian, That got me started down the right path.Huff
H
3

Ok, This solution works but I am bypassing Loopback and the "mongoDB connector". Here is what I am doing.

Given a model named Sequence that looks like this:

{
    "_id": {
        "$oid": "54ab3ec0cc074e24144f26d7"
    },
    "collection": "SpecialOrder",
    "value": 113
}

I am doing this:

mongoConnector = app.dataSources.MyMongoDBConnectorName.connector;

mongoConnector.collection("Sequence").findAndModify({collection: 'SpecialOrder'}, [['_id','asc']], {$inc: { value: 1 }}, {new: true}, function(err, sequence) {
        if(err) {
            console.log(err.message);
        } else {
            // Do what I need to do with new incremented value sequence.value
        }
    });

Seems like there should be a built in LoopbackJS way of doing this. A lot to go through just to increment a value.

Thanks,

Warren Bell

Huff answered 7/1, 2015 at 4:17 Comment(0)
H
2

Have same problem, but with Postgres. Fixed just using altering column 'id' manually in database (set type to SERIAL which means auto-increment in Postgres). I think problem could be resolved in this way on any database.

Haematoxylin answered 26/2, 2015 at 19:56 Comment(1)
all but mongodb... who doesn't seem to be able to do this yetTetanus
D
2

I want to share my approach, which is similar to the author's answer, but with using Loopback's methods. Here is the Sequence model I've created:

{
  "name": "sequence",
  "base": "PersistedModel",
  "idInjection": true,
  "options": {
    "validateUpsert": true
  },
  "properties": {
    "name": {
      "type": "string",
      "required": true
    },
    "value": {
      "type": "number",
      "required": true
    }
  },
  "validations": [],
  "relations": {},
  "acls": [],
  "methods": []
}

You can store as many sequences as you want in this model. Then I create a sequence I need with this script (in this case order sequence):

var app = require('./server/server');

var Sequence = app.models.Sequence;

Sequence.findOrCreate({
  where: {
    name: 'order'
  }
}, {
  name: 'order',
  value: 0
}, function (err) {
  if (err) {
    console.log(err);
  }
  process.exit();
});

Now everytime I need order number to create an order, first I update the order record in Sequence model by incrementing its value and then use it:

var Sequence = Order.app.models.Sequence;

Sequence.findOne({
  where: {
    name: 'order'
  }
})
.then(function (orderNumber) {
  orderNumber.value++;
  return orderNumber.save();
})
.then(function (orderNumber) {
  Order.upsert({
    orderNumber: orderNumber.value,
    ...
  });
});

Cheers!

Dacoity answered 18/12, 2015 at 9:30 Comment(2)
I'm not sure that done like this you would't risk to have id conflict on concurrent requests. I believe increment has to happen inside Sequence model and return only once updated the value in dbTetanus
seems adding a { allowExtendedOperators: true } could do the trick for mongodb. See #40108592Tetanus

© 2022 - 2024 — McMap. All rights reserved.