I'm trying to use the waitFor function of react.js but it seems I'm doing something wrong.
What I want to do i basic, wait for a store to be filled before calling it from another store.
1.Register token in the first store
RipplelinesStore.dispatcherIndex= Dispatcher.register(function(payload) {
var action = payload.action;
var result;
switch(action.actionType) {
case Constants.ActionTypes.ASK_RIPPLELINES:
registerAccount(action.result);
RipplelinesStore.emitChange(action.result);
break;
}
});
2.Write the wait for in the other store
Dispatcher.register(function(payload) {
var action = payload.action;
var result;
switch(action.actionType) {
case Constants.ActionTypes.ASK_RIPPLEACCOUNTOVERVIEW:
console.log("overviewstore",payload);
Dispatcher.waitFor([
RipplelinesStore.dispatcherIndex,
]);
RippleaccountoverviewsStore.test= RipplelinesStore.getAll();
console.log(RippleaccountoverviewsStore.test);
break;
}
return true;
});
Unfortunately my getall() method return an empty object (getAll() is well written). So it seems that the waitFor dispatcher function is not working.
Basically I know that's because the first store is still receiving the answer from the server but I thought that waitFor would waitfor it to be fetched I don't get it.
Any clue ? Thanks!
Edit: I fire the first store fetch like tha. What I don't understand is that I'm dispatching the load once my backbone collection has fetched (I dispatch on succeed with a promise...)
ripplelinescollection.createLinesList(toresolve.toJSON()).then(function() {
Dispatcher.handleViewAction({
actionType: Constants.ActionTypes.ASK_RIPPLELINES,
result: ripplelinescollection
});
});
I also tried to bind the waitfor to an action which is never called but the other store is still not waiting ! WEIRD !
seems like the problem is the async fetch from the server. waitFor isn't supposed to work this way. You will have to introduce another action that is triggered as soon as the data has been received from the server.
Have a look at this answer: https://stackoverflow.com/a/27797444/1717588
Related
I would like to write one nice, tidy "login" function that I use to log in to a bluetooth peripheral by sending it a password.
public async Task<bool> LogIn()
{
bool result = false;
//First log in
var connectHook = Device.ConnectHook(BleService.Control, new Guid[] { BleCharacteristic.PasswordResult });
connectHook.Subscribe(ScanResult =>
{
ScanResult.Characteristic.DisableNotifications();
//Succesful Login
if (ScanResult.Data[0] == 1)
{
result = true;
}
//Failed Login
else
{
result = false;
}
});
await Device.WriteCharacteristic(BleService.Control, BleCharacteristic.Password, PasswordBytes);
await connectHook.FirstAsync();
return result;
}
I basically want to subscribe to the password result characteristic, then write the password, and then wait for the password result before returning from the function.
Is this the place to use a promise? I have read about them but do not understand their use.
Thanks
EDIT:
Did some digging and think I've found a good answer. I've updated the code above to reflect it, let me know what you think.
EDIT 2:
So, the code above doesn't work because nothing is returned from
await connectHook.FirstAsync();
If I comment that line out it all works....but it seems like it's working because I have a race condition and the notification gets back before the other code completes.
Does the function magically await for that notification? I thought the observable implemented IEnumerable and would return the first item as long as it had come back? I'm new to this reactive stuff so please be kind.
In you code:
The method connectHook.Subscribe is a asynchronous method. Before you added the two await methods, the function login will directly return false without wait the callback in connectHook.Subscribe,so the return value in login will not be changed whether you login successfully or failed to login.
After you add the two await methods,I guess the callback in connectHook.Subscribe has been triggered after these two methods finished running. So the return value will be changed with the return value in the callback.
I have function getData() which make an ajax call and retrive JSON data. On success i call another function which is marquee() . inside marquee on finish event i call getData() again, But each time getData() when get called, it increases it's request to mentioned file data.php, For example on first call it call once, Second call it request twice, and then twice become 4times,8times and more and more, how to avoid this?!
function getData()
{
$.get('data.php).done(function(response)
{
var data = JSON.parse(response);
if(data.Direction == "left")
{
$(".marquee").html("<span data-direction='"+data.Direction+"'>"+data.Message+"</span>");
}else if(data.Direction == "right"){
$(".marquee").html("<span data- direction='"+data.Direction+"'>"+data.Message+"</span>");
}
});
}
function marquee()
{
$(".marquee").marquee({duration : 10000}).bind("finished",function()
{
getData();
});
}
I hope i was clear... Appreciate each answer.
Every time you are calling marquee function, you are basically binding an event finished on to it. On multiple such function calls, you will have duplicate events. In your code setup, you need to unbind the function before binding it. Something like
$(".marquee").marquee({duration : 10000}).unbind("finished",getData).bind("finished",getData)
Ideally, you should bind only once so you do not have to unbind it again and again.
So I am working on couple of cases in my app where I need the following to happen
When event triggered, do the following
List item
check if the data with that context is already cached, serve cached
if no cache, debounce 500ms
check if other http calls are running (for the same context) and kill them
make http call
On success cache and update/replace model data
Pretty much standard when it comes to typeahead functionality
I would like to use observables with this... in the way, I can cancel them if previous calls are running
any good tutorials on that? I was looking around, couldn't find anything remotely up to date
OK, to give you some clue what I did now:
onChartSelection(chart: any){
let date1:any, date2:any;
try{
date1 = Math.round(chart.xAxis[0].min);
date2 = Math.round(chart.xAxis[0].max);
let data = this.tableService.getCachedChartData(this.currentTable, date1, date2);
if(data){
this.table.data = data;
}else{
if(this.chartTableRes){
this.chartTableRes.unsubscribe();
}
this.chartTableRes = this.tableService.getChartTable(this.currentTable, date1, date2)
.subscribe(
data => {
console.log(data);
this.table.data = data;
this.chartTableRes = null;
},
error => {
console.log(error);
}
);
}
}catch(e){
throw e;
}
}
Missing debounce here
-- I ended up implementing lodash's debounce
import {debounce} from 'lodash';
...
onChartSelectionDebaunced: Function;
constructor(...){
...
this.onChartSelectionDebaunced = debounce(this.onChartSelection, 200);
}
For debaunce you can use Underscore.js. The function will look this way:
onChartSelection: Function = _.debounce((chart: any) => {
...
});
Regarding the cancelation of Observable, it is better to use Observable method share. In your case you should change the method getChartTable in your tableService by adding .share() to your Observable that you return.
This way there will be only one call done to the server even if you subscribe to it multiple times (without this every new subscription will invoke new call).
Take a look at: What is the correct way to share the result of an Angular 2 Http network call in RxJs 5?
I have a simple ExtJs (3.4) Grid with a Writer. When the user makes some changes the store is saved to the server as follows:
store.on('save', afterSave(resp));
All is fine. However, I want to get a response as to wheather the record has been saved successfully, failed or an update conflict happed. How to best do this?
Are you using Ext.data.proxy.Ajax to load your stores? If so, you can use the reader property to evaluate and handle the server responses.
Another option would be to make AJAX called directly and handle the responses from there as well
I used exception listener to parse the data as suggested here. But, is this the right way to do this.
Ext.data.DataProxy.addListener('exception', function(proxy, type, action,
options, res) {
if (type == 'response') {
var success = Ext.util.JSON.decode(res.responseText).success;
if (success) {
console.log('UPDATE OK');
} else {
console.log('UPDATE FAILED');
}
}
});
I've build a livesearch with the jQuery.ajax() method. On every keyup events it receives new result data from the server.
The problem is, when I'm typing very fast, e.g. "foobar" and the GET request of "fooba" requires more time than the "foobar" request, the results of "fooba" are shown.
To handle this with the timeout parameter is impossible, I think.
Has anyone an idea how to solve this?
You can store and .abort() the last request when starting a new one, like this:
var curSearch;
$("#myInput").keyup(function() {
if(curSearch) curSearch.abort(); //cancel previous search
curSearch = $.ajax({ ...ajax options... }); //start a new one, save a reference
});
The $.ajax() method returns the XmlHttpRequest object, so just hang onto it, and when you start the next search, abort the previous one.
Assign a unique, incrementing ID to each request, and only show them in incrementing order. Something like this:
var counter = 0, lastCounter = 0;
function doAjax() {
++counter;
jQuery.ajax(url, function (result) {
if (counter < lastCounter)
return;
lastCounter = counter;
processResult(result);
});
}
You should only start the search when the user hasn't typed anything for a while (500ms or so). This would prevent the problem you're having.
An excellent jQuery plugin which does just that is delayedObserver:
http://code.google.com/p/jquery-utils/wiki/DelayedObserver
Make it so each cancels the last. That might be too much cancellation, but when typing slows, it will trigger.
That seems like an intense amount of traffic to send an ajax request for every KeyUp event. You should wait for the user to stop typing - presumably that they are done, for at least a few 100 milliseconds.
What I would do is this:
var ajaxTimeout;
function doAjax() {
//Your actual ajax request code
}
function keyUpHandler() {
if (ajaxTimeout !== undefined)
clearTimeout(ajaxTimeout);
ajaxTimeout = setTimeout(doAjax, 200);
}
You may have to play with the actual timeout time, but this way works very well and does not require any other plugins.
Edit:
If you need to pass in parameters, create an inline function (closure).
...
var fun = function() { doAjax(params...) };
ajaxTimeout = setTimeout(fun, 200);
You will want some kind of an ajax queue such as:
http://plugins.jquery.com/project/ajaxqueue
or http://www.protofunc.com/scripts/jquery/ajaxManager/
EDIT:Another option, study the Autocomplete plug-in code and emulate that.(there are several Autocomplete as well as the one in jquery UI
OR just implement the Autocomplete if that serves your needs