I am new to angular and I am building an app where I want to make multiple API calls and update the view as the data from them comes by. I do not want to wait for all the api calls to be completed to update my view and my api calls are not dependent on each other. Some of the API calls takes more than a minute to return the data.
I was thinking of using $q.all since I can start multiple asynchronous tasks, but I can't update the view after each one is completed. Could someone please point out how I can build this ?
Should I just use $scope.$apply in the success block of my $http call ?
My progress so far LINK (this was different issue I had, but the code is the same)
It's a bit hard to understand your model and what you're trying to achieve from you question, but you might want to use something like $broadcast() and $on().
So you'd broadcast an event when you're API has finished downloading:
$scope.$broadcast('API-download', data);
and then listen for it elsewhere and update your view
$scope.$on(
'API-download',
function(data){
processData( data );
}
)
That syntax might not be perfect, and as you have multiple API calls you'll need to broadcast different events like 'API-product-download' and 'API-catalogue-download'
Related
say the code below:
this.props.getRemoteUserId()
this.props.getRemotePrice()
the first function will get the userId and then with that Id I can fetch the new price. My question is : is this.props.getRemotePrice() fired after the new userId has save to the store?
That really depends on what is inside those functions. If they are both asynchronous AJAX calls for instance, then you can never be sure which one will finish first.
As a preface, I'm still new to React, so I'm still fumbling my way through things.
What I have is a component that fetches data to render an HTML table. So I call my Actions' fetchData() (which uses the browser's fetch() API) from within componentWillMount(), which also has a listener for a Store change. This all works well and good, and I'm able to retrieve and render data.
Now the next step. I want to be able to fetch new data when the component's props is updated. But I'm not exactly sure what the proper way to do so is. So I have a three part question
Would the proper place to do my fetchData() on new props be in componentWillReceiveProps(), after validating that the props did change, of course?
My API is rather slow, so it's entirely possible a new prop comes in while a fetch is still running. Is it possible to cancel the old fetch and start a new one, or at least implement logic to ignore the original result and wait for the results from the newer fetch?
Related to the above question, is there a way to ensure only one fetch is running at any time besides having something like an isLoading boolean in my Action's state (or elsewhere)?
Yes, componentWillReceiveProps is the proper place to do that.
Regarding point 2 and 3:
The idea of cancelling the task and maintaining 'one fetch running' seems to be inadequate. I don't think this kind of solution should be used in any system because implementation would limit an efficiency of your app by design.
Is it possible to cancel the old fetch and start a new one, or at least implement logic to ignore the original result and wait for the results from the newer fetch?
Why don't you let a 'newer fetch' response override an 'old fetch' response?
If you really want to avoid displaying the old response you can implement it simply using a counter of all fetchData calls. You can implement it in this way:
var ApiClient = {
processing: 0,
fetchData: function(){
processing++
return yourLibForHTTPCall.get('http://endpoint').then(function (response)){
processing--
return response
}
},
isIdle: function(){
return processing == 0
}
}
and the place where you actually make a call:
apiClient.fetchData(function(response){
if(apiClient.isIdle()){
this.setState({
})
}
}
I hope yourLibForHTTPCall.get returns a Promise in your case.
I am using Jquery stpes plugin for wizard.
Here I have one problem, On step 2 I am making ajax call to get the data and filling into input controls but the problem here is data is refreshing everytime on step changes. so state is not maintain. I have set the enableCacheContent=true, still it's not working.
form.steps({
headerTag: "h3",
bodyTag: "fieldset",
enableContentCache: true})
You can save response data in local variable, and check if the data exist in variable does not make request again
In my app, I make two ajax calls to for one piece of data. First I make a call to get a list of ecommerceIntegrations. Once I have those, I can then grab each of their respective orders.
My current code looks something like this:
componentDidMount: function() {
EcommerceIntegrationStore.addChangeListener(this._onIntegrationStoreChange);
OrderStore.addChangeListener(this._onOrderStoreChange);
WebshipEcommerceIntegrationActionCreators.getEcommerceIntegrations();
},
_onIntegrationStoreChange: function() {
var ecommerceIntegrations = EcommerceIntegrationStore.getEcommerceIntegrations();
this.setState({ecommerceIntegrations: ecommerceIntegrations});
ecommerceIntegrations.forEach(function(integration) {
WebshipOrderActionCreators.getPendingOrdersOfIntegration(integration.id);
});
},
_onOrderStoreChange: function() {
this.setState({
pendingOrders: OrderStore.getAllPendingOrders(),
pendingOrdersByIntegration: OrderStore.getPendingOrdersByIntegration()
});
}
I'm trying to follow Facebook's Flux pattern, and I'm pretty sure this doesn't follow it. I saw some other SO posts about nesting data with Flux, but I still don't understand. Any pointers are appreciated.
Everything here looks good except this:
ecommerceIntegrations.forEach(function(integration) {
WebshipOrderActionCreators.getPendingOrdersOfIntegration(integration.id);
});
Instead of trying to fire off an action in response to another action (or worse yet, an action for every item in ecommerceIntegrations), back up and respond to the original action. If you don't yet have a complete set of data, and you need to make two calls to the server, wait to fire the action until you have all the data you need to make a complete update to the system. Fire off the second call in the XHR success handler, not in the view component. This way your XHR calls are independent of the dispatch cycle and you have moved application logic out of the view and into an area where it's more appropriately encapsulated.
If you really want to update the app after the first call, then you can dispatch an action in the XHR success handler before making the second call.
Ideally, you would handle all of this in a single call, but I understand that sometimes that's not possible if the web API is not under your control.
In a Flux app, one should not think of Actions as being things that can be chained together as a strict sequence of events. They should live independently of each other, and if you have the impulse to chain them, you probably need to back up and redesign how the app is responding to the original action.
I am making a AJAX call using something like:
model.fetch(
dataType: "jsonp",
success: function(data){}
)
My question is if I want to modify the data return from the server, should I do it in success or model.parse(). Also, which method gets executed first?
WARNING: I am a backbone newbie :)
Thank you in advance!
Parse will be triggered first.
The backbone official documentation its not clear about it. It says:
parse is called whenever a model's data is returned by the server, in fetch, and save. The function is passed the raw response object, and should return the attributes hash to be set on the model. The default implementation is a no-op, simply passing through the JSON response. Override this if you need to work with a preexisting API, or better namespace your responses.
It doesn't talk about who is triggered first.
But i test it by my self, and parse was triggered first.
You can test it by yourself, if you don't have an API for test, Use dataType:"jsonp" and try to find a web site that is using REST.You'll see that JsonP is triggered first. :)