Swift & PromiseKit: Resolving ALL promises from a loop - ios

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
}

Related

Using fetch in a loop in code by 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!

How to return value AND promise in Protractor framework

let us suggest the function _headerSave() save to DB some Text header. We need to know both the Header and operate the correspond promise.
How could we do it?
Wrong code example:
header = headerCreate(); //header is the promise but real header needed
function headerCreate(){
var header_name = "Random Header Created";
return _headerSave(header_name); //return promise
}
function _headerSave(header_name){
element(by.css('button[ng-click="HeaderEditCtrl.saveHeader(true)"]')).click().then(function() {
element.all(by.repeater('button in modal.buttons')).get(1).click(); //press Save
browser.driver.wait( function(){
return element(by.css('table[class="grid-table"] span[title="'+header_name+'"]')).isPresent();
}, 5000);
});
return element(by.css('table[class="grid-table"] span[title="'+header_name+'"]'));
}
Promises are objects.
Objects in JavaScript can have properties. You can add those properties dynamically.
function _headerSave(header_name){
// ...
var p = element(by.css('table[class="grid-table"] span[title="'+header_name+'"]'));
p.header_name = header_name;
return p;
}
Usage:
_headerSave(header_name).header_name;
The easiest way to fix the problem is make the code simpler.
Instead of
headerCreate().then(function(HeaderPromise){
element(by.css('div')).then(function(){
console.log(headerPromise.header_name);
});
});
better to write:
headerPromise=headerCreate();
element(by.css('div'));
console.log(headerPromise.header_name);
theControlFlow object allows to do it in this way.

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).

Actionscript - Adding EventListener to multiple buttons on stage

I have a little problem with adding EventListener to multiple objects on stage. I have above 40 buttons on stage named "Button01","Button02" .. "Button40", and i'm looking for easiest way to add EventListener to all of them.
Creating something like
Button01.addEventListener(MouseEvent.CLICK, doSomething)
Button02.addEventListener(MouseEvent.CLICK, doSomething)
..
Button40.addEventListener(MouseEvent.Click, doSomething)
(Notice the same function).
isn't solution i'm looking for :(.
Thanks in advance.
You could do something like this:
var cnt:Number;
var cnt_str:String;
for (cnt = 1; cnt <= 40; cnt++) {
if (cnt < 10) {
cnt_str = "0" + String(cnt);
} else {
cnt_str = String(cnt);
}
this["Button" + cnt_str].addEventListener(MouseEvent.CLICK, doSomething);
}
This assumes that this code is in the DocumentClass, or on your timeline somewhere since it is using this to access the MovieClips. If that is not the case then just replace the this with a reference of the container.

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