I have a scenario where I need to duplicate an object (after or before saving it to Parse) only changing one field.
The problem is, I can't figure out how to find the stop condition when saving this new object and the afterSave callback getting called again and again.
My object:
{
"createdAt": "2015-02-21T23:25:03.525Z",
"creator": {
"__type": "Pointer",
"className": "_User",
"objectId": "2k9OzzBrPr"
},
"date": {
"__type": "Date",
"iso": "2015-02-21T22:46:39.048Z"
},
"description": "Hdheha",
"from": {
"__type": "Pointer",
"className": "_User",
"objectId": "Sd9B1XyZVL"
},
"has_accepted": false,
"has_answered": false,
"objectId": "YQCWRo0j2V",
"status": 0,
"to": {
"__type": "Pointer",
"className": "_User",
"objectId": "2k9OzzBrPr"
},
"updatedAt": "2015-02-21T23:25:03.525Z",
"value": 2.3499999046325684
}
My (try) server code:
function saveMirrorDebit(request) {
var toUser = request.object.get("to");
var fromUser = request.object.get("from");
var invertedDebit = request.object;
var Debit = Parse.Object.extend("Debit");
var query = new Parse.Query(Debit);
query.equalTo("parent_debit", {
__type : "Pointer",
className : "Debit",
objectId : invertedDebit.id
});
query.find({
success : function (debit) {
if (debit) {
console.log('debito nao nulo');
} else {
console.log('debito nulo, criando o espelho invertido');
var newDebit = new Debit();
newDebit.set("creator", invertedDebit.get("creator"));
newDebit.set("from", toUser);
newDebit.set("to", fromUser);
newDebit.set("value", -invertedDebit.get("value"));
newDebit.set("parent_debit", {
__type : "Pointer",
className : "Debit",
objectId : invertedDebit.id
});
newDebit.save(null);
}
},
error : function (error) {
console.log(error);
}
});
}
Which is called on afterSave:
Parse.Cloud.afterSave("Debit", function (request) {
...
saveMirrorDebit(request);
...
}
How can I approach this ?
Thanks
First, I wouldn't recommend you duplicating any object... What are you trying to achieve?
Anyhow, in an afterSave, you can achieve what you want. Note that the beforeSave could save you one API call.
Parse.Cloud.afterSave("Debit", function (request) {
var debit = request.object;
if (!(debit.has("duplicated"))){
var Debit = Parse.Object.extend("Debit");
var duplicated_debit = new Debit();
duplicated_debit.set("creator", debit.get("creator"));
duplicated_debit.set("date", debit.get("date"));
duplicated_debit.set("from", debit.get("from"));
// repeat as many times as needed, include your "change logic here"
// that's where the magic happens
duplicated_debit.set("duplicated",true);
debit.set("duplicated",true);
Parse.Object.saveAll([duplicated_debit,debit]);
}
}
Related
I have a json response like this:
{
"status": "success",
"count": 3,
"data": [
{
"_id": "604b266e7e2dd800159031e4",
"type": "expense",
"description": "This is an income",
"amount": 4555,
"createdAt": "2021-03-12T08:29:34.128Z",
"updatedAt": "2021-03-12T08:29:34.128Z",
"id": "604b266e7e2dd800159031e4"
},
{
"_id": "604b24ac7e2dd800159031e2",
"type": "expense",
"description": "This is an income",
"amount": 4555,
"createdAt": "2021-03-12T08:22:04.802Z",
"updatedAt": "2021-03-12T08:22:04.802Z",
"id": "604b24ac7e2dd800159031e2"
},
{
"_id": "604b24897e2dd800159031e1",
"type": "income",
"description": "This is an income",
"amount": 4555,
"createdAt": "2021-03-12T08:21:29.684Z",
"updatedAt": "2021-03-12T08:21:29.684Z",
"id": "604b24897e2dd800159031e1"
}
]
}
There is a "type" key in the object array whose value can either be "expense" or "income".
Now, in my android, how do I get only data for "expense" and "income" NOT all of them.
Example I want to run this request but get only the type whose value is "expense". How do I do it with Kotlin?
I am using Retrofit
Resource.Status.SUCCESS -> {
if (it.data?.status == "success") {
for (expenditureType in it.data.data){
val type = expenditureType.type
//logic here
}
}
}
val expenseList = it.data.data.filter { it.type = "expense" }
It is as simple as that.
If you want list of all types,
you can get list of string using map function.
val list:List<String> = it.data.data.map {
it.type
}
If you want a filtered list with specific types,
val list = it.data.data.filter {
it.type == "expense" or it.type == "income"
}
I want to sort my main array using a child array value. Output as below:
{
"status": true,
"statusCode": 100,
"message": "",
"data": {
"win": [
{
"id": "1",
"admin": [
{
"id": "38",
"name": "Admin 05",
"point": {
"id": "96",
"name": "96"
}
}
]
},
{
"id": "2",
"admin": [
{
"id": "39",
"name": "Admin 06",
"point": {
"id": "95",
"name": "95"
}
}
]
},
{
"id": "3",
"admin": [
{
"id": "26",
"name": "Admin 05",
"point": {
"id": "98",
"name": "98"
}
}
]
}
]
}
}
I want array as below but I am not able to do so.
id = 3 // first
id = 1 // second
id = 2 // third and so on.
I tried below:
Collections.sort(loWinArray, object : Comparator<Win> {
override fun compare(obj1: Win, obj2: Win): Int {
// ## Ascending order
return (obj2.admin.get(0).point!!.name.toInt() - obj1.admin.get(0).point!!.name.toInt()) // To compare string values
}
})
Can any one please help?
If you want it to be sorted by the point ID, largest first to smallest last, try this:
val sortedArray = loWinArray.sortedByDescending { item -> item.admin.first().id.toInt() }
Try this for ascending order what you have tried it will return descending order
Collections.sort(loWinArray, object : Comparator<Win> {
override fun compare(obj1: Win, obj2: Win): Int {
// ## Ascending order
return obj1.admin.get(0).point!!.name.toInt() - obj2.admin.get(0).point!!.name.toInt()
}
})
I want to send a post request with loopback "invokeStaticMethod".
Please help me how to do it.
I want to send a POST API request to below url:
localhost:3000/api/user/id/unblock With parameter {"userId", "blockId"}
Please let me know how can I send a POST request with Loopback
You could create a remote method like this:
User.unblock = function(id, userId, blockId, callback) {
var result;
// TODO
callback(null, result);
};
Then, the remote method definition in the json file could look like this:
"unblock": {
"accepts": [
{
"arg": "id",
"type": "string",
"required": true,
"description": "",
"http": {
"source": "path"
}
},
{
"arg": "userId",
"type": "string",
"required": false,
"description": "",
"http": {
"source": "form"
}
},
{
"arg": "blockId",
"type": "string",
"required": false,
"description": "",
"http": {
"source": "form"
}
}
],
"returns": [
{
"arg": "result",
"type": "object",
"root": false,
"description": ""
}
],
"description": "",
"http": [
{
"path": "/:id/unblock",
"verb": "post"
}
]
}
Then your remote method would look like this:
You could play around with function arguments and use one body argument instead of 2 form arguments and read the data from there, although I believe that if there are only 2 additional parameters it's better to put them separately. But it depends on your approach.
I believe this is what you are looking for...
https://loopback.io/doc/en/lb3/Adding-remote-methods-to-built-in-models.html
In your case, it should look something like this...
module.exports = function(app) {
const User = app.models.User;
User.unblock = function(userId, blockId, cb) {
... <Your logic goes here> ...
cb(null, result);
};
User.remoteMethod('unblock', {
accepts: [{arg: 'userId', type: 'string'}, {arg: 'blockId', type: 'string'}],
returns: {arg: 'result', type: 'string'}
});
I am used loopback's framework to generate my APIs. Now, I am trying to write a custom "RemoteMethod" that will require a long number (timestamp in unix format such as 1466598625506) and return an array of Sync Objects (I am using retrofit to comunicate with the endpoints). In my android app when I call the end point "getRecodsAfterTimestamp" it should return the records with equal or bigger timeStamp value than the provided one in the request. What It returns is all of the records (3 at this time).
This is how my model (sync.json) called Sync looks like:
{
"name": "Sync",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"uuid": {
"type": "string"
},
"table": {
"type": "string"
},
"action": {
"type": "string"
},
"timeChanged": {
"type": "number"
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}
And this is my sync.js with the remote method looks like:
module.exports = function(Sync) {
Sync.getRecodsAfterTimestamp = function(timestamp, cb){
// var response;
Sync.find({where:{ or: [
{timeChanged:timestamp},
{timeChanged: {gt:timestamp } }
] }}, function(err, sync) {
cb(null,sync);
// response.push(sync);
});
// cb(null, response);
}
Sync.remoteMethod (
'getRecodsAfterTimestamp',
{
http: {path: '/getRecodsAfterTimestamp', verb: 'get'},
accepts: {arg: 'timeChanged', type: 'number', http: { source: 'query' } },
returns: {
arg: 'data',
type: 'array',
root: true
}
}
);
};
I dont know if it matters but this is my retrofit method declaration:
#GET("Syncs")
Call<List<Sync>> getAllSyncsAfterThisTimeStamp(#Query(("getRecodsAfterTimestamp?timeChanged=")) long timeChanged);
And here I am calling it like that:
Long timeStamp = 1466598625506L;
Log.e(TAG, "Job Service task is running...");
getAllSyncsCall = espcService.getAllSyncsAfterThisTimeStamp(timeStamp);
getAllSyncsCall.enqueue(EspcJobSheculerService.this);
This code returns
This is not the result I want. It should have returned all of the records after 1466598625506 which is two records only.
Your query is correct.
Check in find callback you get right output or not
I'm getting my position from an address, I use this website:
I get JSON data, but I dont know how to read it in my Android app.
{
"name": "plaza mayor 1 madrid España",
"Status": {
"code": 200,
"request": "geocode"
},
"Placemark": [ {
"id": "p1",
"address": "Plaza Mayor, 1, 28012 Madrid, España",
"AddressDetails": {
"Accuracy" : 8,
"Country" : {
"AdministrativeArea" : {
"AdministrativeAreaName" : "Comunidad de Madrid",
"SubAdministrativeArea" : {
"Locality" : {
"LocalityName" : "Madrid",
"PostalCode" : {
"PostalCodeNumber" : "28012"
},
"Thoroughfare" : {
"ThoroughfareName" : "Plaza Mayor, 1"
}
},
"SubAdministrativeAreaName" : "Madrid"
}
},
"CountryName" : "España",
"CountryNameCode" : "ES"
}
},
"ExtendedData": {
"LatLonBox": {
"north": 40.4164186,
"south": 40.4137207,
"east": -3.7053139,
"west": -3.7080118
}
},
"Point": {
"coordinates": [ -3.7066379, 40.4150359, 0 ]
}
} ]
}
How can I read the "coordinates" tag?
Thank you in advance!
parse it, to begin with, then access the various elements :
JSONObject response = new JSONObject(responseAsString);
JSONObject point = response.getJSONArray("Placemark").getJSONObject(0).getJSONObject("Point");
double lat = point.getJSONArray("coordinates").getDouble(0);
and so on
I would suggest using some sort of framwork to handle your Json data, here's a good aexample. Then you can handle your data as a regular object.
Sending and Parsing JSON Objects
Good luck!