Wednesday, July 18, 2018

How to Use Decimal128 in Loopback Via REST Api

Leave a Comment

I would like to utilise the MongoDB Decimal128 Data type in loopback. Note: I don't want to use the Number type.

My model:

{   "name": "Mongoproduct",   "options": {     "validateUpsert": true,     "strictObjectIDCoercion": true,     "relations": {},     "mongodb": {       "collection": "products",       "allowExtendedOperators": true     }   },   "properties": {     "id": {       "type": "String",       "required": true,       "length": null,       "precision": null,       "scale": null     },     "sku": {       "type": "String",       "required": false,       "length": 50,       "precision": null,       "scale": null,     },     "buyprice": {       "type": "object",       "mongodb": {         "dataType": "Decimal128"       }     },   }   "validations": [],   "relations": {},   "acls": [],   "methods": {} } 

If I query the data through the REST explorer , a record will look something like this:

{     "id": "5b41a6ac1afe940d900cba75",     "sku": "shGHYB12-60-LOZ",     "buyPrice": {       "$numberDecimal": "20.4927"     }, } 

If I try and save the same data through a REST Put request , I get the following:

{   "error": {     "statusCode": 500,     "name": "MongoError",     "message": "The dollar ($) prefixed field '$numberDecimal' in 'buyPrice.$numberDecimal' is not valid for storage.",     "driver": true,     "index": 0,     "code": 52,     "errmsg": "The dollar ($) prefixed field '$numberDecimal' in 'buyPrice.$numberDecimal' is not valid for storage.",     "stack": "MongoError: The dollar ($) prefixed field '$numberDecimal' in 'buyPrice.$numberDecimal' is not valid for storage.\n    at Function.MongoError.create (C:\\node\\ztest\\ztest_data\\node_modules\\mongodb-core\\lib\\error.js:31:11)\n    at toError (C:\\node\\ztest\\ztest_data\\node_modules\\mongodb\\lib\\utils.js:139:22)\n    at C:\\node\\ztest\\ztest_data\\node_modules\\mongodb\\lib\\collection.js:1059:67\n    at C:\\node\\ztest\\ztest_data\\node_modules\\mongodb-core\\lib\\connection\\pool.js:469:18\n    at process._tickCallback (internal/process/next_tick.js:61:11)"   } } 

I have tried a number of things , different MongoDB types ( decimal , Decimal128 , NumberDecimal etc ) . I have tried putting allowExtendedOperators in the datasource config .

According to the loopback docs https://loopback.io/doc/en/lb3/MongoDB-connector.html#type-mappings:

Type conversion is mainly handled by Mongodb. See ‘node-mongodb-native’ for details

And According to the Native types https://docs.mongodb.com/manual/reference/bson-types/ I should be able to specify "decimal". ( I am using Mongodb 4.0 )

Any help is greatly appreciated.

1 Answers

Answers 1

As you are using Node.js, you can use mongoose to easily achieve what you are looking for. Mainly Loopback does not any other datatype than the Number (see here). I think here's what you can do.

You can do it in this way:

var mongoose = require('mongoose');  var testModel = mongoose.Schema({     "buyprice": {         "type": mongoose.Schema.Types.Decimal128     } });  // I have added only the Decimal128 field, you can define your schema here.  const Col = mongoose.model(`test`, testModel);  Col.create({ buyprice: '0.78' }).     then(doc => console.log('Document: ', doc.toObject())).     catch(error => console.error(error)); 

This will output:

Document:  { _id: 5b4ee53c95eeb452b4239eaf,   buyprice:    Decimal128 {      _bsontype: 'Decimal128',      bytes: <Buffer 4e 00 00 00 00 00 00 00 00 00 00 00 00 00 3c 30> },   __v: 0 } 

Read more.

Hope this helps you!!

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment