LoopBackJs REST API Create response not returning full model, only form data - loopbackjs

when I POST to api/testmodel using an object with only the required fields, the object is being created correctly in the DB. However, I only get the object I sent in the request body. I'm trying to get the full object with null fields in the response.
Thanks for the help!
{
"name": "test",
"plural": "test",
"base": "PersistedModel",
"idInjection": true,
"replaceOnPUT": false,
"properties": {
"city": {
"type": "string",
"length": 100
},
"name": {
"type": "string",
"required": true,
"length": 100
},
"id": {
"type": "string",
"id": true,
"required": true,
},
"officePhone": {
"type": "string",
"length": 100
},
"status": {
"type": "string",
"required": false,
"length": 200
},
"street": {
"type": "string",
"length": 100
}
},
"methods": {}`

Then you need to create default values for your model, for example city:
"properties": {
"city": {
"type": "string",
"length": 100,
"default": ""
},
...

In your controller, after you have created your new record and have the record ID, perform a findById query and return that object instead of the object returned from create. This should give you a response similar to a GET route.

Related

Data Fusion - Argument Setter plugin throws Null pointer exception

Argument setter - HTTP post endpoint url.
Below is the argument setter plugin configuration.
{
"name": "Argument Setter",
"plugin": {
"name": "ArgumentSetter",
"type": "action",
"label": "Argument Setter",
"artifact": {
"name": "argument-setter-plugins",
"version": "1.1.1",
"scope": "USER"
},
"properties": {
"method": "POST",
"connectTimeout": "60000",
"readTimeout": "60000",
"numRetries": "0",
"followRedirects": "true",
"url": "-----url----",
"body": "{\"type\": \"DELTA\", \"fileType\": \"CSV\", \"targetName\": \"DATAFUSION_TEST_1\", \"dataPoolId\": \"4d3164d9-c8e4-4042-9c69-ff758a17b140\"}"
}
},
"outputSchema": [
{
"name": "id",
"type": "string",
"nullable" : true
},
{
"name": "targetName",
"type": "string",
"nullable" : true
},
{
"name": "lastModified",
"type": "int",
"nullable" : true
},
{
"name": "lastPing",
"type": "string",
"nullable" : true
},
{
"name": "status",
"type": "string",
"nullable" : true
},
{
"name": "type",
"type": "string",
"nullable" : true
},
{
"name": "fileType",
"type": "string",
"nullable" : true
},
{
"name": "targetSchema",
"type": "string",
"nullable" : true
},
{
"name": "upsertStrategy",
"type": "string",
"nullable" : true
},
{
"name": "fallbackVarcharLength",
"type": "string",
"nullable" : true
},
{
"name": "dataPoolId",
"type": "string",
"nullable" : true
},
{
"name": "connectionId",
"type": "string",
"nullable" : true
},
{
"name": "postExecutionQuery",
"type": "string",
"nullable" : true
},
{
"name": "sanitizedPostExecutionQuery",
"type": "string",
"nullable" : true
},
{
"name": "allowDuplicate",
"type": "boolean",
"nullable" : true
},
{
"name": "tableSchema",
"type": "string",
"nullable" : true
},
{
"name": "mirrorTargetNames",
"type": "array",
"nullable" : true
},
{
"name": "changeDate",
"type": "int",
"nullable" : true
},
{
"name": "keys",
"type": "array",
"nullable" : true
},
{
"name": "logs",
"type": "array",
"nullable" : true
},
{
"name": "csvParsingOptions",
"type": "string",
"nullable" : true
},
{
"name": "optionalTenantId",
"type": "string",
"nullable" : true
}
]
}
],
Response from the endpoint url is like below
[{
"id": "b489dc71-96fd-4e94-bcc5-9a4b3732855e",
"targetName": "POSTMAN_TBL",
"lastModified": 1631598169840,
"lastPing": null,
"status": "NEW",
"type": "DELTA",
"fileType": "PARQUET",
"targetSchema": null,
"upsertStrategy": "UPSERT_WITH_UNCHANGED_METADATA",
"fallbackVarcharLength": null,
"dataPoolId": "f37b8619-30e2-4804-9355-38d123142ac4",
"connectionId": null,
"postExecutionQuery": null,
"sanitizedPostExecutionQuery": null,
"allowDuplicate": false,
"tableSchema": null,
"changeDate": 1631598169840,
"mirrorTargetNames": [],
"keys": [],
"logs": [],
"csvParsingOptions": null,
"optionalTenantId": null
}
]
When I execute this, I get 200 response after hitting the endpoint url.
But the pipeline is failing with NullPointerException
java.lang.NullPointerException: null
at io.cdap.plugin.ArgumentSetter.handleResponse(ArgumentSetter.java:73) ~[na:na]
at io.cdap.plugin.http.HTTPArgumentSetter.run(HTTPArgumentSetter.java:76) ~[na:na]
at io.cdap.cdap.etl.common.plugin.WrappedAction.lambda$run$1(WrappedAction.java:49) ~[na:na]
Can someone help me what am I missing here?
As mentioned in the comments, the response from the server has to be structured in the following format:
{
"arguments" : [
{ argument }, { argument }, ..., {argument}
]
}
Since your response is not structured in this format, you are getting a NullPointerException when you execute your pipeline.
See docs for reference https://github.com/data-integrations/argument-setter/tree/9f6aabbf28e00644726d485188235b406cac522f#usage

ReferenceError: g is not defined loopback extended models

I am having a nearly identical problem to my previous question. When a user model is created, the following error is returned:
ReferenceError: g is not defined
at new ModelConstructor (eval at createModelClassCtor (/usr/src/app/node_modules/loopback-datasource-juggler/lib/model-builder.js:671:21), <anonymous>:10:27)
at user.ModelBaseClass._initProperties (/usr/src/app/node_modules/loopback-datasource-juggler/lib/model.js:349:28)
at user.ModelBaseClass (/usr/src/app/node_modules/loopback-datasource-juggler/lib/model.js:60:8)
at user.Model (eval at createModelClassCtor (/usr/src/app/node_modules/loopback-datasource-juggler/lib/model-builder.js:671:21), <anonymous>:12:24)
at user.PersistedModel (eval at createModelClassCtor (/usr/src/app/node_modules/loopback-datasource-juggler/lib/model-builder.js:671:21), <anonymous>:12:24)
at user.User (eval at createModelClassCtor (/usr/src/app/node_modules/loopback-datasource-juggler/lib/model-builder.js:671:21), <anonymous>:12:24)
at new user (eval at createModelClassCtor (/usr/src/app/node_modules/loopback-datasource-juggler/lib/model-builder.js:671:21), <anonymous>:12:24)
at Function.DataAccessObject.create (/usr/src/app/node_modules/loopback-datasource-juggler/lib/dao.js:359:13)
at /usr/src/app/node_modules/loopback-datasource-juggler/lib/dao.js:1262:13
at /usr/src/app/node_modules/loopback-datasource-juggler/lib/dao.js:2175:62
at /usr/src/app/node_modules/loopback-datasource-juggler/lib/dao.js:2111:9
at /usr/src/app/node_modules/loopback-datasource-juggler/node_modules/async/dist/async.js:1012:9
at /usr/src/app/node_modules/loopback-datasource-juggler/node_modules/async/dist/async.js:359:16
at eachOfArrayLike (/usr/src/app/node_modules/loopback-datasource-juggler/node_modules/async/dist/async.js:928:9)
at eachOf (/usr/src/app/node_modules/loopback-datasource-juggler/node_modules/async/dist/async.js:990:5)
at _asyncMap (/usr/src/app/node_modules/loopback-datasource-juggler/node_modules/async/dist/async.js:1005:5)
at Object.map (/usr/src/app/node_modules/loopback-datasource-juggler/node_modules/async/dist/async.js:995:16)
at allCb (/usr/src/app/node_modules/loopback-datasource-juggler/lib/dao.js:2025:13)
at /usr/src/app/node_modules/loopback-connector-mongodb/lib/mongodb.js:1155:9
at result (/usr/src/app/node_modules/mongodb/lib/utils.js:414:17)
at executeCallback (/usr/src/app/node_modules/mongodb/lib/utils.js:406:9)
at handleCallback (/usr/src/app/node_modules/mongodb/lib/utils.js:128:55)
Here are my models:
user.json:
{
"name": "user",
"plural": "users",
"base": "User",
"idInjection": false,
"options": {
"validateUpsert": true
},
"properties": {
"id": {
"type" : "string",
"id" : true,
"required" : true,
"defaultFn" : "guid"
},
"type": {
"type" : "[string]",
"required" : true,
"default" : ["student"]
},
"full_name": {
"type": "string",
"required": false
},
"office" : {
"type": "string",
"required" : false
},
"profile_img": {
"type": "string",
"required": false
},
"departmentId": {
"type": "string",
"required": false
}
},
"validations": [],
"relations": {
"department": {
"type": "belongsTo",
"model": "department"
},
"syncedcalendar" : {
"type" : "hasMany",
"model" : "syncedcalendar"
},
"accessTokens": {
"type": "hasMany",
"model": "accessToken",
"foreignKey": "userId",
"options": {
"disableInclude": true
}
}
},
"acls": [],
"methods": {}
}
accessToken.json
{
"name": "accessToken",
"plural": "accessTokens",
"base": "AccessToken",
"properties": {},
"validations": [],
"idInjection": false,
"relations": {
"user": {
"type": "belongsTo",
"model": "user",
"foreignKey": "userId"
}
},
"acls": [],
"methods": []
}
The error above (in both this case and my previous issue) resulted because loopback could not parse the model's json file. In this case, it was the type property of user:
"type": {
"type" : "[string]",
"required" : true,
"default" : ["student"]
},
It seems the default cannot be an array. Removing this default and enforcing this default in a hook resolved the issue.
I went through an issue that resembled yours. And yes, the error stack gives too little useful info. It should instead say: "please stick to Loopback types" because that's the problem. You're stuck with Loopback types.
In your case, the parser couldn not handle an array. Well, it turns out it won't parse an un recognized type string either. For example, if you try to declare a property as integer:
"id":
{
"type": "Integer", <----- not a loopback type
"id": 1,
"mysql":
{
"columnName": "id",
"dataType": "int",
}
},
It will throw, because the native type is Number. You can format it as integer, but don't mess with its type.
"id":
{
"type": "Number", <---- one of loopback types. Integer is not one of them
"id": 1,
"mysql":
{
"columnName": "id",
"dataType": "int",
}
"format":"integer" <---- here's where you can format or cast as desired
},
If your database values are json-like (so they should rehidrate as arrays and objects) just declare them as Objects.

Loopback: How to define a property with an array of strings in Loopback?

I have the following model in a loopback application, that will be persisted in a MongoDB:
Model
Name Coffeshop:
Id
Name (string)
City (String)
Question:
Now i want to be able to store a list of strings in a new property called "tags":
Tags (Array of string)
There is no relation to other models necessary. I need just a plain flat list of strings.
How can i achieve this?
Code:
{
"name": "CoffeeShop",
"plural": "CoffeeShops",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"name": {
"type": "string",
"required": true
},
"city": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}
Thats easy:
{
"name": "CoffeeShop",
"plural": "CoffeeShops",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"name": {
"type": "string",
"required": true
},
"city": {
"type": "string",
"required": true
},
"tags": {
"type": [
"string"
],
"required": false
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}

Createmany in Strongloop Loopback

I have an Order model which hasMany OrderItem models. But once a client wants to create an Order, it has to create an Order object first then for each product he added to his basket, he needs to create responding OrderItems separately. As you may notice it causes many reduntant requests. May be I can make a custom method for OrderItems which consumes a product list. But i was wondering if there is a built in mechanism for this like createMany since it is a very useful operation.
ORDER MODEL
{
"name": "Order",
"plural": "Orders",
"base": "PersistedModel",
"idInjection": true,
"properties": {
"customerId": {
"type": "number",
"required": true
},
"branchId": {
"type": "number",
"required": true
}
},
"validations": [],
"relations": {
"orderItems": {
"type": "hasMany",
"model": "OrderItem",
"foreignKey": "orderId"
}
},
"acls": [],
"methods": []
}
ORDERITEM MODEL
{
"name": "OrderItem",
"plural": "OrderItems",
"base": "PersistedModel",
"idInjection": true,
"properties": {
"UnitPrice": {
"type": "number"
},
"productId": {
"type": "number",
"required": true
},
"purchaseOrderId": {
"type": "number",
"required": true
},
"quantity": {
"type": "number"
}
},
"validations": [],
"relations": {
"product": {
"type": "belongsTo",
"model": "Product",
"foreignKey": "productId"
},
"purchaseOrder": {
"type": "belongsTo",
"model": "PurchaseOrder",
"foreignKey": ""
}
},
"acls": [],
"methods": []
}
Loopback "create" method accepts also an array of objects (see PersistedModel.create docs) so you should try creating one "create" call and send an array of OrderItems.

Is the referral (fb_action_ids) value, stored within the activity made by a user on a timeline app?

I'm testing a timeline app I just made.
I'm using Graph API Explorer for testing.
I tested the next URL:
https://graph.facebook.com/10150691128476714
where 10150691128476714 is the id of the activity I made through my app.
It returns the next values:
{
"id": "10150691128476714",
"from": {
"name": "Moisés Briseño Estrello",
"id": "719621713"
},
"start_time": "2012-04-26T07:22:00+0000",
"end_time": "2012-04-26T07:22:00+0000",
"publish_time": "2012-04-26T07:22:00+0000",
"application": {
"name": "appname",
"namespace": "appname",
"id": "367747679937600"
},
"data": {
"objectname": {
"id": "10150825002710211",
"url": "https://young-planet-1642.herokuapp.com/AMLO.html",
"type": "appname:objectname",
"title": "TItle"
}
},
"type": "appname:actionname",
"likes": {
"count": 0,
"can_like": true,
"user_likes": false
},
"comments": {
"count": 0,
"can_comment": true
}
}
I wonder if the referral (fb_action_ids) value is also stored in here or where I can find it?
Thanks in advance :)
ID of the action is the fb_action_ids value, i.e. fb_action_ids = 10150691128476714.