How to execute onEnter after the onExit api call callback - angularjs

I call an API on every OnEnter to retrieve the state of my data.
The state of the data is updated on every OnExit by calling a POST on API.
So the test of my state is always late from one state, because the call on the API to retrieve data is called before the save on the State from the onExit.
My question is how to run OnEnter from the OnExit api call callback ?
Thanks

Save the onExit promise and chain the onEnter from it.
var promise = restangularAPI.post();
promise.then ( function () {
restangularAPI.get();
});
If the post has already completed the get will execute immediately. Otherwise the $q service will wait for the post to complete before executing the get.

Related

Api call in render method of reactjs

I have a code in which an API call is made inside the render method in a react app, is it correct?
The API call is made from a function placed inside a const function which is placed in another file
render method is place for presenting various elements to user and these elements can be used to trigger an api-call for various purposes. For example - checking validity of text entered in input-element, sending form-data async-ly to server, etc.
And this is a nice practice to put the code into various modules or separate files for better management, etc. for ex. call is wrapped inside a function and placed in a different file. Webpack helps in filling all various modules in place.
So it is alright to put api calls in render and calling a function defined inside another file for the same.
It is not correct.
1) If the api call is waiting for the call to complete(await or promise resolve), Then it is essentially blocking render.
2) React might call render function many times[it may or not lead to DOM update], which means you will be making redundant api calls as many times.
It is ok to do so, if it is in response to an event.
So No, just put the api call in componentDidMount or ComponentDidUpdate or if you are using hook, add a useEffect.
Good Luck!
It really depends on the use case.
There is nothing wrong with doing so as long as you aren't calling it everytime it re-renders. I assume you are making the request upon triggering of certain events(such as onClick). If yes, it may be cleaner to encapsulate it within a method.
async doSomething = () => {
// do the rest
// make API request
await getRequest();
}
return <>
<button onClick={() => this.doSomething()}/>
</>;
If the request is to be made only once and when the component is initialised, you should make that request within the componentDidMount lifecycle hook. According to the documentation for componentDidMount,
componentDidMount() is invoked immediately after a component is
mounted (inserted into the tree). Initialization that requires DOM
nodes should go here. If you need to load data from a remote endpoint,
this is a good place to instantiate the network request.
Otherwise, calling it on render() will result in the API request to be triggered everytime there is a re-render.

How do I execute a method after a successful async action in React and Redux?

I'm trying to execute some code after a successful async action using React Saga. Ideally I would return a Promise to achieve that, but it doesn't seem to be the case. I also tried to use the componentDidUpdate method but it's not executed after the action. How can I do that? Thank you in advance.
You can pass a call back function when you are calling the action. And after the successful completion of the async operation you can execute the callback function inside the saga.

ComponentWillMount and ComponentDidMount not synced

I am making a react application. I need to make an ajax call to fetch the data from server and populate this data in the rows of my component's table. I do my ajax call in componentWillMount and store the response in the state. Now my render fetched this state and populates it. I have a few questions though:
Am I doing it right to place ajax in componentWillMount?
My componentDidMount doesn't get the value of state which get's set in componentWillMount. This means the async is not complete while componentDidMount is trying to access it. How to solve this? setting async:false is really a bad option.
What all thing can be used in componentWillMount?
Yes, componentWillMount is called once before the render. This is the place to fetch data.
Probably when the component finished rendering, the componentDidMount called although the async operation didn't finished yet, therefore you get empty result.
You can use componentWillUpdate
componentWillUpdate() is invoked immediately before rendering when new
props or state are being received. Use this as an opportunity to
perform preparation before an update occurs. This method is not called
for the initial render.
Or shouldComponentUpdate,
shouldComponentUpdate() is invoked before rendering when new props
or state are being received. Defaults to true. This method is not
called for the initial render or when forceUpdate() is used.
It's a broad question, basically fetching data from actions, calling api's etc.
More info in docs
Am I doing it right to place ajax in componentWillMount?
The recommend approach is to place your initial network requests that modify state inside of componentDidMount, because in theory your ajax request could come back prior to React completing the mounting process which might lead to your state getting overwritten.
However, in practise people use both as the above scenario should never happen.
My componentDidMount doesn't get the value of state which get's set in
componentWillMount. This means the async is not complete while
componentDidMount is trying to access it.
That is the correct behaviour.
How to solve this? setting
async:false is really a bad option.
If you stop it then it's no longer async.
The best practise here would be to show a loading indicator:
add a loading property to state
set it to true just above your fetch request
inside .then and .catch set loading to false
inside render check if your data has arrived - if not display the loading indicator
If you don't want to show anything until your request comes back
You can return null inside of render which will prevent your component from being added to the DOM. You can then combine this with a flag state property to make sure the component gets mounted once your request comes back, i.e. something like this:
render() {
if (!this.state.initialRequestHasCompleted) return (null);
return (
<div>
...
</div>
);
}
What all thing can be used in componentWillMount?
What is the purpose of having functions like componentWillMount in React.js?

Is there any way to cancel all the requests in $q.all()?

When a user switch a state when another state is being loaded, I am destroying the controller of the previous state. But there are still some promises in the previous state that are yet to be resolved. So even after destroying the state controller, The then() method of these promises are being called. So I wanted to cancel all the existing promises by calling resolve() on the promises on destroying the controller. But the promise returned by $q.all() does not have a resolve() method. Nor does it return the individual promises on which I can call resolve to abort the promises. Is there any way that I can achieve this?

$stateChangeSuccess getting hit twice

I have an $http call that is made inside of a function getRoutes that fires off whenever that state has changed:
$scope.$on('$stateChangeSuccess', function(event) {
$scope.getRoutes($stateParams);
})
I have another function that changes a state parameter and then calls $state.go():
$scope.bindSelectedRoute = function(){
$stateParams.pickup_route= this.d.pickup_route;
$state.go('track.search', $stateParams);
}
My problem is that the http call keeps being made twice. First with the $stateParams correct and then a second call with an empty object getting passed. I'm assuming this is a core part of angular that I'm missing.
Any hints?
Best.
I can't suggest refactored code for you but I believe the answer is because you did a $state.go(). You already told the app to fire $scope.getRoutes($stateParams) when the stateChangeSuccess is fired so when $state.go() fires and it successfully changes the state, $scope.getRoutes($stateParams) gets fired again.

Resources