As of April 12th, you must go to Progress SupportLink to create new support cases or to access existing cases. Please, bookmark the SupportLink URL and use the new portal to contact the support team.
Hi Andre,
The request object represents the incoming request from the app to the Kinvey backend. The response object represents the outgoing response from the Kinvey backend to the app for that incoming request.
The request body might or might not be empty depending on the request format. And response.body will be an array of rows with zero or more entries.
Following lines seem to be the culprit
var profile = request.body; var creator = profile._acl.creator;
If the request returns only one row, above line should look as follows:
var profile = response.body; var creator = profile[0]._acl.creator;
I hope this is helpful.
Regards,
Wani
Getting runtime errors for the code now.
function onPostFetch(request, response, modules) { var emailCollection = modules.collectionAccess.collection("emails"); var profileCollection = modules.collectionAccess.collection("profile"); var info = modules.logger.info; var profile = request.body[0]; if (profile) { var creator = profile._acl.creator; modules.async.each(response.body, function(aProfile, callback) { emailCollection.find({"_acl.creator" : creator}, function(err,emails){ if (!err) { info("Emails: " + emails); aProfile.emailAddresses = emails; info(aProfile); } callback(); }); }, function(err){ response.continue(); }); } else { response.continue(); } }
What I'm trying to do here is, on postFetch, fetch all e-mail addresses from Emails collection matching the same _acl.creator as the Profile. Is that even possible? (i.e. "filling" Profile fields with information from other collections on every fetch operation - I'm using this approach to ensure better scaling possibilities and also up-to-date data)
Hi,
Can you share the runtime errors that you are getting?
To reiterate the use case, when you fetch profiles from "profile" collection, in postFetch BL, you want to get entries from "email" collection respective to that profile and append it to the response JSON. Is that right?
Regards,
Wani
Hello Wani,
I'm no longer getting any runtime errors, just the following 200 response:
200 SUCCESS -- [ { "_id": "546b864cb76664a0030084e7", "firstName": "TEST", "middleName": "TEST", "lastName": "TEST", "nickname": "TEST", "company": "TEST", "department": "TEST", "jobTitle": "TEST", "prefix": "TEST", "suffix": "TEST", "notes": "TEST", "addresses": [ "Test 1", "Test 2" ], "emailAddresses": [ "Bogus" ], "keycode": "kid_-yEfkj_t7", "_acl": { "creator": "kid_-yEfkj_t7" }, "_kmd": { "lmt": "2015-12-06T20:40:35.246Z", "ect": "2014-11-18T17:47:56.300Z" } }, { "_id": "563fa230891ccddd53049832", "_acl": { "creator": "kid_-yEfkj_t7" }, "firstName": "Madonna", "lastName": "Ciccone", "nickname": "Madge", "jobTitle": "Pop singer", "_kmd": { "lmt": "2015-11-08T19:27:44.960Z", "ect": "2015-11-08T19:27:44.960Z" } }, { "_id": "563fa93cd2c9f27544027711", "_acl": { "creator": "kid_-yEfkj_t7" }, "firstName": "Finalmente", "lastName": "Porra", "middleName": "Foi", "_kmd": { "lmt": "2015-11-08T19:58:34.300Z", "ect": "2015-11-08T19:57:48.870Z" } }, { "_id": "56649dc7af5de3b318004687", "_acl": { "creator": "kid_-yEfkj_t7" }, "_kmd": { "lmt": "2015-12-06T20:42:47.575Z", "ect": "2015-12-06T20:42:47.575Z" } } ]
My code right now, as it stands, never fills "emailAddresses" with results from Email collection:
function onPostFetch(request, response, modules) { var emailCollection = modules.collectionAccess.collection("emails"); var profileCollection = modules.collectionAccess.collection("profile"); var info = modules.logger.info; var profile = request.body[0]; if (profile) { var creator = profile._acl.creator; modules.async.each(response.body, function(aProfile, callback) { emailCollection.find({"_acl.creator" : creator}, function(err,emails){ if (!err) { info("Emails: " + emails); aProfile.emailAddresses = emails; info(aProfile); } callback(); }); }, function(err){ response.continue(); }); } else { response.continue(); } }
Is that code correct? Should I be seeing the data from the Email collection "merged" with the Profile fetch results right on the test console? Or perhaps in the data browser? Or do hooks only work when making "real" requests using the API? I'm not very familiar with Javascript, so I'm trying to infer behaviors from my native mobile experience.
Hi,
There are a couple of issues with this code:
function onPostFetch(request, response, modules) { var emailCollection = modules.collectionAccess.collection("emails"); var profileCollection = modules.collectionAccess.collection("profile"); var info = modules.logger.info; var async = modules.async; if (response.body.length > 0){ async.map(response.body, function(aProfile, callback) { emailCollection.find({"_acl.creator" : aProfile._acl.creator}, function(err,emails){ if (err) { callback(err); } else { // info("Emails: " + emails); aProfile.emailAddresses = emails; // info(aProfile); callback(null,aProfile); } }); , function(err, results){ if (err){ info(err); response.complete(500); } else { response.body = results; response.complete(200); } }); } }
To answer your other question, the hooks work the same way with editor or with a request of any other type - from the mobile app or from Kinvey API console.
Also, I would suggest following resources that will help with Business Logic in future:
Regards,
Wani
Thank you very much for the Business Logic resources, the examples in there are actually quite useful.
I tried your corrections on my code had a timeout error. Is this kind of approach not a good idea with Kinvey (i.e. merging tables via hooks)?
function onPostFetch(request, response, modules) { var emailCollection = modules.collectionAccess.collection("emails"); var profileCollection = modules.collectionAccess.collection("profile"); var info = modules.logger.info; var async = modules.async; if (response.body.length > 0) { async.map(response.body, function(aProfile, callback) { emailCollection.find({"_acl.creator" : aProfile._acl.creator}, function(err,emails) { if (err) { callback(err); } else { // info("Emails: " + emails); aProfile.emailAddresses = emails; // info(aProfile); callback(null,aProfile); } }) , function(err, results) { if (err){ info(err); response.complete(500); } else { response.body = results; response.complete(200); } } }); } }
500 INTERNAL SERVER ERROR -- { "error": "BLTimeoutError", "description": "The Business Logic script did not complete. Please contact support", "debug": "The script was terminated due to timing constraints: took more than 2000ms to complete. Did you forget to call response.complete() or response.continue()?" } REQUEST 2015-12-19T20:37:32-02:00
Hi,
For your current pricing plan, the BL timeout limit is 2 seconds.
The important thing here is the number of rows you are trying to process. Can you give me rough estimates for the following:
Right now I only have 3 Profiles, and only one of them fetches 2 Emails. So I guess Kinvey takes more than 2 seconds for a one-record merge operation. Is that expected?
Regards,
André
andre_felipe
I have a collection called Profile, and I want to populate its emailAddresses column with the results of a postFetch query (that query looks for emails in the Emails collection). However, I can't get the entire operation to even start because the request body is always empty, giving me a null profile var.
Am I wrongly assuming the request object is filled at all times, and has the Profile collection row in its body property?