Zapier Scripting: Catch error and rewrite response - zapier

The app I'm integrating returns a 400 bad request when the search doesn't find a match which Zapier sees as an error.
How can I catch the error and return a [] to tell Zapier there is no match?
Here's the existing post_search code of got:
match_person_email_post_search: function(bundle) {
console.log(bundle.response.content);
var res = JSON.parse(bundle.response.content);
var data;
if(res.person!==null)
{
data = [ res.person ];
}
else
{ data = []; }
return data;
},
I should probably mention I'm a rookie at this scripting!
Thanks!

As long as the search API result returns something, you should be able to capture that using Zapier scripting. Assuming your Zapier search key is contact_data, here is how the function would look:
var Zap = {
search_contact_post_search: function(bundle) {
return bundle.response.content;
}
};
So you can check (within that function) if the data is empty or containing something other than search data, and just return an empty array:
var Zap = {
search_contact_post_search: function(bundle) {
var response_content = JSON.parse(bundle.response.content);
if (!response_content.some_field) {
return [];
}
}
};

Related

I am running into an issue using ImportJSON w/ Google Sheets to import data

I am trying to set up a database of all player items with overalls and series. I can pull the top level (items) but anything below that I get an "Error Getting Data".
https://docs.google.com/spreadsheets/d/1BbIrzYJEqEw_eOqgKXBueDhTUKGLIlMaQVbwEIT5f9Q/edit?usp=sharing
I tried using bradjasper's ImportJSON script but kept getting:
Exception: Attribute provided with no value: url
ImportJSONAdvanced # importJSON.gs:217
var jsondata = UrlFetchApp.fetch(url, fetchOptions);
ImportJSON # importJSON.gs:68
return ImportJSONAdvanced(url, null, query, parseOptions, includeXPath_, defaultTransform_);
The one I am currently using is below and I was able to pull "items" but "items/name" or anything else fails to retrieve data. I am new to this and have been dredging around the web trying to find a solution without success. You guys have been extremely helpful in the past, any insight would be much appreciated.
* Imports JSON data to your spreadsheet Ex: IMPORTJSON("http://myapisite.com","city/population")
* #param url URL of your JSON data as string
* #param xpath simplified xpath as string
* #customfunction
*/
function IMPORTJSON(url,xpath){
try{
// /rates/EUR
var res = UrlFetchApp.fetch(url);
var content = res.getContentText();
var json = JSON.parse(content);
var patharray = xpath.split("/");
//Logger.log(patharray);
for(var i=0;i<patharray.length;i++){
json = json[patharray[i]];
}
//Logger.log(typeof(json));
if(typeof(json) === "undefined"){
return "Node Not Available";
} else if(typeof(json) === "object"){
var tempArr = [];
for(var obj in json){
tempArr.push([obj,json[obj]]);
}
return tempArr;
} else if(typeof(json) !== "object") {
return json;
}
}
catch(err){
return "Error getting data";
}
} ```
Try this one :
var resTable = [];
function getDataJSON(url,xpath){
var data = JSON.parse(UrlFetchApp.fetch(url).getContentText())
var json = eval('data.items')
if (typeof xpath == 'object'){var liste = xpath.join().split(",")} else {var liste = xpath.split("|")}
if (json.length){json.forEach(function(elem){getData(elem,liste)})} else {getData(json,liste)}
return resTable
}
function getData(elem,liste){
var prov=[]
liste.forEach(function(chemin){
var t=chemin.split('/');
var obj=elem;
for (var i=1;i<t.length;i++){obj=obj.item(t[i])}
if(typeof obj=='object'){prov.push('['+obj+']')}else{prov.push(obj)}
})
resTable.push(prov)
}
Object.prototype.item=function(i){return this[i]};
https://docs.google.com/spreadsheets/d/1oy00ZZJCDYlzyCfdeIchvOUaCttbzuUeCKkacDuHeuk/copy

Graph API: What is the correct way to interrupt Pagination

I am using this script to fetch Chats. I need 100 chats maximum but it may happen that a chat do not have 100 messages. How can I handle that case in this script?
I am using Node Package Microsoft Graph Client.
const { Client, PageIterator } = require('#microsoft/microsoft-graph-client');
async getChatList(GroupChatId) {
let messages = [];
let count = 0;
let pauseAfter = 100; // 100 messages limit
let response = await this.graphClient
.api(`/chats/${GroupChatId}/messages`)
.version('beta')
.get();
let callback = (data) => {
messages.push(data);
count++;
return count < pauseAfter;
}
let pageIterator = new PageIterator(this.graphClient, response, callback);
await pageIterator.iterate();
return messages;
}
As I answered on the GitHub issue you opened, the iterator should stop all by itself if it runs out of items to iterate before hitting your "maximum". However, I think you're hitting a bug in the specific API you're using /chats/id/messages.
The problem is that this API is returning a nextLink value in it's response even if there are no next pages. It shouldn't be, and I'm reporting that to the Teams folks. That's causing the pageIterator to try to get the next set of results, which returns 0 items and a nextLink. You're stuck in an infinite loop.
So because of this, using the pageIterator just won't work for this API. You'll need to do the iteration yourself. Here's some TypeScript code to show it:
let keepGoing: Boolean = true;
do
{
// If there are no items in the page, then stop
// iterating.
keepGoing = currentPage.value.length > 0;
// Loop through the current page
currentPage.value.forEach((message) => {
console.log(JSON.stringify(message.id));
});
// If there's a next link follow it
if (keepGoing && !isNullOrUndefined(currentPage["#odata.nextLink"]))
{
currentPage = await client
.api(currentPage["#odata.nextLink"])
.get();
}
} while (keepGoing);
You need to check with a conditional statement if the message has value or not.
The pseudo code is given below:
let callback = (data) => {
if(data != "" || data != null)
{
messages.push(data);
count++;
return count < pauseAfter;
}
else{
return;
}
}

q promise and map doesn't change after iteration

I'm using Q Promises to retrieve data from my redis repository. The problem I'm having, is that through each iteration, the array object (localEncounter) I'm using to store data returned from the chained functions is never updated at each iteration. Previously, I tried to solve this with a foreach loop and spread but the results were the same.
How should I correct this so that localEncounter is updated at each iteration, and ultimately localEncounters contains correct data when returned? Thank you.
var localEncounters = [];
var localEncounter = {};
Promise.all(ids.map(function(id) {
return localEncounter, getEncounter(id, client)
.then(function (encounter) {
encounterObject = encounter;
//set the fields for the return object
localEncounter['encounterid'] = encounterObject[f_id];
localEncounter['screeningid'] = encounterObject[f_screening_id];
localEncounter['assessmentid'] = encounterObject[f_clinical_assessment_id];
localEncounter['psychevalid'] = encounterObject[f_psych_eval_id];
//get screening
return getScreening(encounterObject[f_screening_id], client);
})
.then(function (screening) {
//set the fields for the return object
localEncounter['screeningbegintime'] = screening[f_begin_time];
//get assessment
return getAssessment(localEncounter['assessmentid'], client);
})
.then(function (assessment) {
//set the fields for the return object
localEncounter['assessmentbegintime'] = assessment[f_begin_time];
//get psycheval
//localEncounters.push(assessment);
return getPsychEval(localEncounter['psychevalid'], client);
})
.then(function (psychEval) {
//set the fields for the return object
localEncounter['assessmentbegintime'] = psychEval[f_begin_time];
localEncounters.push(localEncounter);
}
, function (reason) {
console.log(reason); // display reason why the call failed;
reject(reason, 'Something went wrong creating the encounter!');
})
})).then(function(results) {
// results is an array of names
console.log('done ');
resolve(localEncounters);
})
Solution: I only needed to move the declaration of localEncounter inside the map iterator
before:
var localEncounter = {};
Promise.all(ids.map(function(id) {
after:
Promise.all(ids.map(function(id) {
var localEncounter = {};
This now allows that each id iteration gets its own localEncounter object.

breeze observableArray binding - are properties observable?

I have a viewmodel which consists of a list(foreach loop) of DoctorPrices and when clicking on an item in the list it open up a CRUD form on the side. However when i update the values on the CRUD the observableArray that is bound to the foreach is not refreshing? (although the values are updates in the DB correctly)
From my data access module i call the following query.
function getDoctorServices(doctorId) {
var query = breeze.EntityQuery
.from('DoctorPrices')
.where('DoctorID', 'eq', doctorId).orderBy('ListOrder');
return manager.executeQueryLocally(query);
}
In my viewmodel i have the following code:
this.services = ko.computed(function() {
return doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID());
});
services is bound using a foreach loop (not posting here as the code is simple and works)
When i click on a one of the DoctorPrices it gets the data as follows and places it in an observable:
this.selectedPrice = function (data, event) {
self.currentService(data);
self.showEdit(true);
};
I then bind selectPrice to a simple form that has the properties on it to be modified by the user. I then call manager.SaveChanges().
This results in the following problem: the value is being updated correctly but the GUI / Original List that is bound in the foreach is not being updated? Are the properties in breeze not observables? What is the best way to work with something like this.
I thought of a workaround and changing the code with something like this:
doctorList.viewModel.instance.currentDoctorID.subscribe(function() {
self.services([]);
self.services(doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID()));
});
But i feel that clearing the array in that way is sloppy and not the right way of doing things specially with long lists.
Can someone please point me in the right direction on how to bind observableArray properties properly so they are updated?
Additional code my VM Component:
function services() {
var self = this;
this.showForm = ko.observable(false);
this.currentService = ko.observable();
this.services = ko.observableArray(doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID()));
this.title = ko.observable();
doctorList.viewModel.instance.currentDoctorID.subscribe(function() {
self.services([]);
self.services(doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID()));
self.showDetails(false);
});
this.show = function (value) {
self.showForm(value);
};
this.showDetails = ko.observable(false);
this.addNewService = function() {
self.currentService(doctorServices.createService(doctorList.viewModel.instance.currentDoctorID()));
console.log(self.currentService().entityAspect.entityState);
self.showDetails(true);
};
this.showDelete = ko.computed(function() {
if (self.currentService() == null)
return false;
else if (self.currentService().entityAspect.entityState.isDetached()) {
self.title('Add new service');
return false;
} else {
self.title('Edit service');
return true;
}
});
this.deleteService = function() {
self.currentService().entityAspect.setDeleted();
doctorServices.saveChanges();
doctorList.viewModel.instance.currentDoctorID.notifySubscribers();
};
this.closeDetails = function () {
doctorServices.manager.rejectChanges();
doctorList.viewModel.instance.currentDoctorID.notifySubscribers();
self.showDetails(false);
};
this.selectService = function (data, event) {
self.currentService(data);
self.showDetails(true);
};
this.saveChanges = function () {
console.log(self.currentService().entityAspect.entityState);
if (self.currentService().entityAspect.entityState.isDetached()) {
doctorServices.attachEntity(self.currentService());
}
console.log(self.currentService().entityAspect.entityState);
doctorServices.saveChanges();
doctorList.viewModel.instance.currentDoctorID.notifySubscribers();
self.currentService.notifySubscribers();
self.showDetails(true);
};
}
return {
viewModel: {
instance: new services()
},
template: servicesTemplate,
};
Below is my Breeze Data Class:
define('data/doctorServices', ['jquery', 'data/dataManager', 'knockout','mod/medappBase', 'breeze', 'breeze.savequeuing'], function ($, manager, ko,base, breeze, savequeuing) {
var services = ko.observableArray([]);
return {
attachEntity:attachEntity,
getServices: getServices,
services: services,
manager:manager,
getDoctorServices: getDoctorServices,
getServiceById: getServiceById,
createService:createService,
hasChanges: hasChanges,
saveChanges: saveChanges
};
function getServices() {
var query = breeze.EntityQuery.from("DoctorPrices");
return manager.executeQuery(query).then(function (data) {
services(data.results);
}).fail(function (data) {
console.log('fetch failed...');
console.log(data);
});;
}
function getDoctorServices(doctorId) {
var query = breeze.EntityQuery
.from('DoctorPrices')
.where('DoctorID', 'eq', doctorId).orderBy('ListOrder');
var set = manager.executeQueryLocally(query);
return set;
}
function getServiceById(serviceId) {
return manager.createEntity('DoctorPrice', serviceId);
//return manager.getEntityByKey('DoctorPrice', serviceId);
}
function handleSaveValidationError(error) {
var message = "Not saved due to validation error";
try { // fish out the first error
var firstErr = error.innerError.entityErrors[0];
message += ": " + firstErr.errorMessage;
base.addNotify('error', 'Could not save.', message);
} catch (e) { /* eat it for now */ }
return message;
}
function hasChanges() {
return manager.hasChanges();
}
function attachEntity(entity) {
manager.addEntity(entity);
}
function createService(doctorId) {
return manager.createEntity('DoctorPrice', { DoctorPricingID: breeze.core.getUuid(), DoctorID:doctorId }, breeze.EntityState.Detached);
};
function saveChanges() {
return manager.saveChanges()
.then(saveSucceeded)
.fail(saveFailed);
function saveSucceeded(saveResult) {
base.addNotify('success', 'Saved.', 'Your updates have been saved.');
}
function saveFailed(error) {
var reason = error.message;
var detail = error.detail;
if (error.innerError.entityErrors) {
reason = handleSaveValidationError(error);
} else if (detail && detail.ExceptionType &&
detail.ExceptionType.indexOf('OptimisticConcurrencyException') !== -1) {
// Concurrency error
reason =
"Another user, perhaps the server, " +
"may have deleted one or all of the settings." +
" You may have to restart the app.";
} else {
reason = "Failed to save changes: " + reason +
" You may have to restart the app.";
}
console.log(error);
console.log(reason);
}
}
});
Please note this is my frist attempt at both a data class and VM. At the moment i am relying heavily on clearing the array ([]) and using notifySubscribers to make the array refresh :(
I bet you're missing an observable somewhere. I can't tell because you keep hopping from property to property whose definition is not shown.
For example, I don't know how you defined this.currentService.
I'm confused by this:
this.services = ko.computed(function() {
return doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID());
});
Why is it a ko.computed? Why not just make it an observable array.
self.service = ko.observableArray();
// ... later replace the inner array in one step ...
self.service(doctorServices.getDoctorServices(
doctorList.viewModel.instance.currentDoctorID()));
I urge you to follow the observability trail, confident that your Breeze entity properties are indeed observable.
vm.selectedPrice = ko.dependentObservable(function () {
return doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID());
}, vm);
vm is ur model on which u applied bindings , try this it will work.

I need to filter the yui datatable which has inline cell editing. and the data is coming from the groovy controller in key:value pair form. as JSON

hi i am also facing the data error problem. i wanted to filter the data coming from json result from the groovy controller in key:value pair. even if i chage the TYPE_JSON to TYPE_JSARRAY,i am getting NoRecordas found in data table but the json result has the data.
please can u correct me.
Thanks in advance!!
dobMenuButton.subscribe("selectedMenuItemChange",function(e) {
var value =e.newValue.value;
if(YAHOO.lang.isValue(value)) {
myDataTable.getDataSource().sendRequest(null, {
success:function(request, response, payload) {
this.initializeTable();
var rs = response.results;
var filtered = [];
for(var i = 0; i < rs.length; i++) {
if(((rs[i].dateOfBirth).format("MM/dd/yyyy")) == value) {
filtered[filtered.length] = rs[i];
}
}
this.getRecordSet().reset();
MCMPagination.paginatorvar.setTotalRecords(filtered.length,true);
this.getRecordSet().setRecords(filtered, 0);
this.render();
},
scope:myDataTable,
argument:myDataTable.getState()
});
}
});

Resources