Unexpected __data in mongodb loopback v3 - node.js

Why my database has field __data that exactly copying the real data but wouldn't update if the data is changed?
Here is the example of the data :
{
"id": ObjectId("600ffdf0317f9617960b7df6"),
"userId" : "bf959bb8-78a6-426b-b372-cf5a1f9ef731",
"name": "Product 1",
"isActive": true,
"createdAt": ISODate("2021-05-26 11:33:04.992Z"),
"updatedAt": null,
"__data": {
"id": "600ffdf0317f9617960b7df6",
"userId" : "bf959bb8-78a6-426b-b372-cf5a1f9ef731",
"name": "Product 1",
"isActive": true,
"createdAt": ISODate("2021-05-26 11:33:04.992Z"),
"updatedAt": null,
},
}
when I update the data lets say, {"name": "Product 1 New"}, but the "__data.name" still "Product 1"
The problem is when I get the data using find() or findById(), the result is showing "Product 1" which is get from the __data instead of the real data.
I'm using loopback v3 and using mongodb for the database.
Below is my schema for product.
product.json
{
"name": "products",
"base": "PersistedModel",
"plural": "products",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"id": {
"type": "string",
"id": true
},
"userId": {
"type": "string"
},
"name": {
"type": "object"
},
"isActive": {
"type": "boolean",
"default": false
},
"createdAt": {
"type": "date",
"default": "$now"
},
"updatedAt": {
"type": "date",
"default": "$now"
},
},
"validations": [],
"relations": {
"user": {
"type": "belongsTo",
"model": "reseller",
"foreignKey": "userId"
}
},
"acls": [
],
"scope": {
"order": ["createdAt DESC"]
},
"methods": {}
}
How to solve this?
I want to get the response is the real data which is the updated one, and how to avoid to have field __data?

In case somebody stumbled on this even though LB3 is pretty much dead and IBM is trying to kill off LB4.
My problem was the difference between update() and updateAll(), updateAll() seem to add the data object in mongodb not sure why or how if change to update() is should be fine.

Related

Custom junction table in strapi

I have recently started working on strapi and was looking at the relations inside model in their documentation. My scenario is as follows. I have a model named course and another named tag. They have many to many relationship between them.This is what ./api/course/models/course.settings.json has when I made the relation between them named as tag2.
{
"connection": "default",
"collectionName": "course",
"info": {
"name": "course"
},
"options": {
"increments": true,
"timestamps": true
},
"attributes": {
"image_link": {
"type": "string"
},
"created_by": {
"columnName": "created_by_id",
"plugin": "users-permissions",
"model": "user"
},
"updated_by": {
"columnName": "updated_by_id",
"plugin": "users-permissions",
"model": "user"
},
"title": {
"type": "string"
},
"short_description": {
"type": "text"
},
"slug": {
"type": "string",
"unique": true
},
"tags2": {
"collection": "tag",
"via": "courses",
"dominant": true
}
}
}
When I specify the relation using the admin panel strapi itself made a junction table named as courses_tags_2_s__tags_courses.
Here is what tag model looks like
{
"connection": "default",
"collectionName": "tag",
"info": {
"name": "tag",
"mainField": "ui_label"
},
"options": {
"increments": true,
"timestamps": true
},
"attributes": {
"code": {
"type": "string"
},
"description": {
"type": "string"
},
"created_by": {
"plugin": "users-permissions",
"model": "user",
"columnName": "created_by_id"
},
"updated_by": {
"plugin": "users-permissions",
"model": "user",
"columnName": "updated_by_id"
},
"ui_label": {
"type": "string"
},
"courses": {
"via": "tags2",
"collection": "course"
}
}
}
I have a couple of questions
1) Is there a way I can set up the junction table as courses_tags ? i.e overriding the strapi one
2) I have set my mainField as "ui_label" in tag.settings.json but in the admin panel while editing course table content(rows in course table), in the related field of tag2 I see "code" field shown there instead of "ui_label". How to set the mainField?
Note: I have setup strapi with mysql server.
so to answer your first question, there is currently no way to override the join table between two models. This is totally auto-generated by Strapi.
For the second question, this part of the docs is out to date.
To manage display information you will have to use the content manager configuration in the admin panel.
Here a short video - https://www.youtube.com/watch?v=tzipS2CePRc&list=PL7Q0DQYATmvhlHxHqfKHsr-zFls2mIVTi&index=5&t=0s
For 1) Is there a way I can set up the junction table as courses_tags ? i.e overriding the strapi one:
You can specify the following option:
"collectionName": "courses_tags"

Loopback relation

How to do the relation to match with an array of data in loopback
For e.g
My Models
// Regions model
{
"name": "regions",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"title": {
"type": "string",
"required": true
},
"images": {
"type": [
{
"target_id": {
"type": "string"
}
}
]
},
},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}
// Images model
{
"name": "images",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"name": {
"type": "string",
"required": true
},
"url": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": { },
"acls": [],
"methods": {}
}
Expected output:
[
{
"title": "Region 1",
"field_images": [{
"name": "Image 2",
"url": "/media/image-1600x650.jpg",
},{
"name": "Image 1",
"url": "/media/image-1600x650.jpg",
}]
} ]
Assuming that the relationship is HasMany
{
"name": "regions",
"base": "PersistedModel",
...
"relations": {
"images": {
"type": "hasMany",
"model": "images",
"foreignKey": "title", //region title
}
}
...
}
A relationship is defined between two models. So, I highly doubt you would get the images inside an array (if you want to define a relationship between them).
But on loopback you can use separate APIs to retrieve the field_images instead of getting it as an array.
For example - you could retrieve the images like this
region.images([filter],
function(err, images) {
...
});

Loopback Api Explorer Create Error: Invalid Date

I´m using the API explorer of loopback to create a model with the following parameters:
{
"name": "string",
"last_name": "string",
"phone": 0,
"is_invited": true,
"realm": "string",
"username": "string",
"credentials": {},
"challenges": {},
"email": "string",
"emailVerified": true,
"status": "string",
"created": "2016-06-03",
"lastUpdated": "2016-06-03",
"id": 0
}
However, The server is always returning a 500 invalid Date error:
{
"error": {
"name": "Error",
"status": 500,
"message": "Invalid date: Invalid Date",
"stack": "Error: Invalid date: Invalid Date\n at DateType }
}
This is my model for reference. It inherits the User model of Loopback.
{
"name": "ExeboardUser",
"base": "User",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"name": {
"type": "string",
"required": true
},
"last_name": {
"type": "string"
},
"phone": {
"type": "number",
"required": true
},
"is_invited": {
"type": "boolean",
"required": true
}
},
"validations": [],
"relations": {
"boards": {
"type": "hasMany",
"model": "Board",
"foreignKey": "exeboardUserId",
"through": "ExeboardUserBoard"
}
},
"acls": [
{
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW",
"property": "logout"
}
],
"methods": {
}
}
Can anyone tell me what´s the problem with the date? I think it is correctly formated because it´s the default parameters that the explorer generates.
Don't know if you are interested in the answer, but I recently started working with loopback and got the same error as you, the date format that was accepted by the server is like this 2017-01-06T23:58:10.000Z
Hope it helps someone.
Ps.: if the date is not required by the model, don't even send it, not even with "null" or "" value, it will throw a 500 status error.
The correct date format is : 2017-10-12T10:31:37.925Z
And If you want to add fields of dateCreated and dateUpdate, Then use date mixin loopback-ds-timestamp-mixin
Install mixin with
npm i loopback-ds-timestamp-mixin --save
Add the mixins property to your server/model-config.json:
{
"_meta": {
"sources": [
"loopback/common/models",
"loopback/server/models",
"../common/models",
"./models"
],
"mixins": [
"loopback/common/mixins",
"../node_modules/loopback-ds-timestamp-mixin",
"../common/mixins"
]}
}
And in your model:
{
"name": "ExeboardUser",
"base": "User",
"idInjection": true,
"options": {
"validateUpsert": true
},
"mixins": {
"TimeStamp" : true
},
"properties": {
"name": {
"type": "string",
"required": true
},
"last_name": {
"type": "string"
},
"phone": {
"type": "number",
"required": true
},
"is_invited": {
"type": "boolean",
"required": true
}
},
"validations": [],
"relations": {
"boards": {
"type": "hasMany",
"model": "Board",
"foreignKey": "exeboardUserId",
"through": "ExeboardUserBoard"
}
},
"acls": [
{
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW",
"property": "logout"
}
],
"methods": {
}
}
When dealing with stringified params you should send the date value as a string in simplified extended ISO format in your query filter.
Here is an example of how you can do this in a very simple way using toISOString method:
const dataValue = new Date('10 May 2018 19:30 UTC');
console.log(dataValue.toISOString());
// output: 2018-05-10T19:30:00.000Z

How do I get Loopback to prefer short ids when doing id injection?

I have a loopback app which gives ids like "56dbfa7089223aca7946ca14" when creating models. I would prefer ids like "0" or "73". Is there a way to adjust id-injection practices to have ids start at 0 and increment as base-10 integers?
The data store is MongoDB v2.6.10)
running loopback v2.22 on node v5.7.1 on Ubuntu 15.10
Here's the relevant model.json
{
"name": "Term",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"name": {
"type": "string",
"required": true
},
"beginDate": {
"type": "date",
"required": true
},
"endDate": {
"type": "date",
"required": true
}
},
"validations": [],
"relations": {
"lessons": {
"type": "hasMany",
"model": "Lesson",
"foreignKey": ""
},
"classes": {
"type": "hasMany",
"model": "Class",
"foreignKey": ""
},
"weeklySchedules": {
"type": "hasMany",
"model": "WeeklySchedule",
"foreignKey": ""
}
},
"acls": [],
"methods": {}
}
there are several ways to do it, you can read about them in official documentation
It is stated by mongo developers, that is completely ok, to use your own id, if you really need it, so go for it.
However if you do it only because you "dont want ObjectId, because it does not look good", I suggest you, to get used to it.

Add the current user before store a model strongloop

I recently start with Strongloop framework,
I made a simple model
{
"name": "income",
"plural": "incomes",
"base": "PersistedModel",
"idInjection": true,
"properties": {
"description": {
"type": "string",
"required": true
},
"amount": {
"type": "number",
"required": true
},
"when": {
"type": "date",
"required": true
}
},
"validations": [],
"relations": {
"user": {
"type": "belongsTo",
"model": "User",
"foreignKey": ""
}
},
"acls": [],
"methods": []
}
I want make a relation with current session user and the income record. but I can't find a example for that.
You can use the current context, there is a code example at the bottom of the link, but you have to expand it:
Link

Resources