Using fetch in a loop in code by zapier - zapier

I want to do 3 different api call from my zapier code, get their returns in variables and merge them. I can't figure out how to do that. It will be like:
var urls = [apiUrl1, apiUrl2, apiUrl3];
var output = [];
for ( i = 0; i < urls.length; i++ ) {
output[i] = fetch( urls[i] );
}
This is an example code. I can't get response to output, it gets only a blank object {}. What will be the procedure to save the fetch return values in the output array?

Since apparently the folks at Zapier do not like to give out working examples or any sort of decent documentation for this level of code intricacy... here is a working example:
var promises = [];
for (var i = urls.length - 1; i >= 0; i--) {
promises.push(fetch(urls[i]));
}
Promise.all(promises).then(function(res){
var blobPromises = [];
for (var i = res.length - 1; i >= 0; i--) {
blobPromises.push(res[i].text());
}
return Promise.all(blobPromises);
}).then(function(body){
var output = {id: 1234, rawData: body};
callback(null, output);
}).catch(callback);
This may not be the cleanest solution, but it works for me. Cheers!

Two things you'll need to brush up on:
Promises - especially Promise.all() - there is lots out there about that.
Callback to return the data asynchronously. Our help docs describe this.
The main reason your code fails is because you are assuming the fetch happens immediately. In JavaScript that is not the case - it happens Async and you have to use promises and callbacks to wait until they are done before returning the output via the callback!

Related

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;
}
}

Swift & PromiseKit: Resolving ALL promises from a loop

I'm looking for a solution in Swift3 to resolve a dynamic number of promises all at once, e.g. like this sample in JavaScript:
var promises = [];
for(var i = 0; i < 5; i++) {
var promise = $http.get('/data' + i);
promises.push(promise);
}
$q.all(promises).then(doSomethingAfterAllRequests);
https://daveceddia.com/waiting-for-promises-in-a-loop/
There was a library call 'Craft' for Swift2 that could do that (https://github.com/supertommy/craft), but it's no longer maintained.
Does anyone know if or how I could do that with PromiseKit or another library?
Thx a bunch!
You can look into when which may provide what you need and is covered here.
Use the loop to put your promises into an array and then do something like this:
when(fulfilled: promiseArray).then { results in
// Do something
}.catch { error in
// Handle error
}

How save multiple values JSONStore

I need to replace multiple value in JSONStore of IBM Worklight.
In this way is saved only first value. Why?
.then(function() {
for (var index = 0; index < elencoSpese.length; index++) {
var spesa = elencoSpese[index];
var spesaReplace = {_id: spesa.id, json: spesa};
spesa.id_nota_spesa = idNotaSpesa;
spesa.checked = true;
WL.JSONStore.get(COLLECTION_NAME_SPESE).replace(spesaReplace);
}
})
You want to build an array of JSONStore documents and pass it to the replaceAPI. For example:
.then(function() {
var replacementsArray = [];
for (var index = 0; index < elencoSpese.length; index++) {
var spesa = elencoSpese[index];
var spesaReplace = {_id: spesa.id, json: spesa};
spesa.id_nota_spesa = idNotaSpesa;
spesa.checked = true;
replacementsArray.push(spesaReplace);
}
return WL.JSONStore.get(COLLECTION_NAME_SPESE).replace(replacementsArray);
})
.then(function (numOfDocsReplaced) {
// numOfDocsReplaced should equal elencoSpese.length
})
I assume this happens in the JavaScript implementation of the JSONStore API, if that's the case the answer is in the documentation here. The JavaScript implementation of JSONStore expects code to be called serially. Wait for an operation to finish before you call the next one. When you call the replace multiple times without waiting, you're calling the API in parallel instead of serially. This should not be an issue in the production environments (i.e. Android, iOS, WP8 and W8).

Getting all the active jobs from Quartz.NET scheduler

How I can get all the active jobs scheduled in the Quartz.NET scheduler? I tried the GetCurrentlyExecutingJobs() but it is returning always 0.
That method doesn't seem to work.
The only solution I had found was to loop through all the jobs:
var groups = sched.JobGroupNames;
for (int i = 0; i < groups.Length; i++)
{
string[] names = sched.GetJobNames(groups[i]);
for (int j = 0; j < names.Length; j++)
{
var currentJob = sched.GetJobDetail(names[j], groups[i]);
}
}
When a job is found it means that it is still active.
If you set your job as durable, though, it will never be deleted if there are no associated trigger.
In that situation this code works better:
var groups = sched.JobGroupNames;
for (int i = 0; i < groups.Length; i++)
{
string[] names = sched.GetJobNames(groups[i]);
for (int j = 0; j < names.Length; j++)
{
var currentJob = sched.GetJobDetail(names[j], groups[i]);
if (sched.GetTriggersOfJob(names[j], groups[i]).Count() > 0)
{
// still scheduled.
}
}
}
UPDATE:
I did some debugging to see what happens with GetCurrentlyExecutingJobs().
As a matter of fact it returns the job being executed but the elements are remove from the collection as soon as the job is executed.
You can check the 2 functions JobToBeExecuted and JobWasExecuted in the QuartzScheduler class.
A simpler loop option would be to get all of the job keys and iterate over them. This implementation is for a minimal API example. It gets all JobKeys from the scheduler and then iterates over each on to get the details and execution schedule. More details available in this sample repo: QuartzScheduler. If a job doesn't have a schedule, or it's scheduled execution has completed and there are no future executions planned then the job will not be included in the list of returned jobs.
app.MapGet("/schedules", async (ISchedulerFactory sf) =>
{
var scheduler = await sf.GetScheduler();
var definedJobDetails = new List<JobDetailsDto>();
var jobKeys = await scheduler.GetJobKeys(GroupMatcher<JobKey>.AnyGroup());
foreach (var jobKey in jobKeys)
{
var jobDetail = await scheduler.GetJobDetail(jobKey);
var jobSchedule = await scheduler.GetTriggersOfJob(jobKey);
if (jobDetail != null && jobSchedule != null)
{
definedJobDetails.Add(new JobDetailsDto(
jobDetail.Key.Name,
jobDetail.Key.Group,
jobDetail.Description,
jobSchedule.First().GetPreviousFireTimeUtc(),
jobSchedule.First().GetNextFireTimeUtc())
);
}
}
return definedJobDetails;
})

Flex AsyncToken implementation on Rails

i'm using a Rails backend with my App and getting a AsyncToken returned from it (a DB-Call to be specific)
As far as i know the AsyncToken returns a result event when done loading all data from the request, this way its possible to make sure all data was loaded before executing some function which uses the data.
i tried the following implementation to get the AsyncToken converted into an Array and plotting its objects as strings to the user:
var dataSrv:services.databaseservice.DatabaseService = new services.databaseservice.DatabaseService;
dataSrv.addEventListener(ResultEvent.RESULT, dbListener);
//DBOPERATION returns my AsyncToken
var listData:AsyncToken = dataSrv.DBOPERATION;
var responder:AsyncResponder = new AsyncResponder( resultHandler, faultHandler );
listData.addResponder(responder);
public function resultHandler(event:ResultEvent, token:Object=null):void{
var output: Array = (event.result as Array);
for (var i:int = 0; i<output.length; i++){
Alert.show( output[i].toString() );
}
}
public function faultHandler(event:FaultEvent, token:Object=null):void{
Alert.show( "FAULT: " + event.fault.message );
}
But i keep getting a "null object-pointer" error!
Ok here how it works:
var output:ArrayCollection = (event.result as ArrayCollection);
for (var i:int = 0; i<output.length; i++)
{
// where VARIABLE is the name of the transmitted data-variable
Alert.show(output[i].VARIABLE);
}
hope this helps others. Thx for Help Guys, stackoverflow is just awesome!
You could add a breakpoint on the following line
var output: Array = (event.result as Array);
Then go to the Flash Debug perspective, in the "Variables" pane you should be able to access the properties of the event and see the content of the result property.
If the result property is null, you may want to double check what is returned from Rails

Resources