What's the correct way of doing API requests in React for components that update? - ajax

I have two components: App and Movie. In my App component I show a list of movie ID's (they come from my local database), and in the Movie component I show a detailed view of the Movie ID that has been clicked.
Inside the Movie component I fetch some data from the IMDB API for the matching ID. The movie ID gets passed to the Movie as a prop.
No Movie component is shown by default. If a Movie ID is clicked, the Movie component is shown. Once it is shown, another Movie ID can be clicked from the list and the Movie component must be updated with the newly fetched data from the API.
What is the correct way of doing the API requests? If I do it in componentDidMount(), then an API request will only happen the first time the Movie component renders. If I do it in componentWillReceiveProps(), then the Movie component only does the request if it got updated after it has rendered. Is it okay to just use both componentDidMount and componentWillReceiveProps? Or is there a more appropriate way?

Try using componentWillMount which will be fired before the component has mounted.
Here is a good guide regarding component lifecycle.

Related

Data-view is not updating when entity is updated in Mendix

Question is: How to show data in data-view in such a way that if entity is updated some how dataview is updated too.
This is my Entity named latestReading.
Here is my page LatestReading that show latest readings. It contains three data views.
This page is not called directly, as it expect a object latestReading. Hence a micro-flow named showLatestReadingPage is executed that fetches or create latestReading object and pass it to the LatestReading page and display LatestReading page.
Here is that micro-flow.
getOrCreateLatestReading is a micro-flow that returns us the a latestReading object if it is available or create a new latestReading object if it is not already created and then returns it.
Here is that micro-flow.
These are the properties of first of the three data-views in LatestReading page as shown diagram of LatestReading Page above. Name of this DataView is TemperatureDataView
These are the properties of text widget that is inside TemperatureDataView data-view. Its name is temperatureText. It shows value of temperature in the TemperatureDataView.
And this is the caption of temperatureText text widget:
Problem is when another micro-flow updates the value of latestReading the text widget is not updated. I need to reload it by clicking on navigation link of LatestReading page again.
I need my text widget in data view to keep updating value of latestReading when it is updated my some other micro-flow
The issue is that ‘refresh in client’ only works if the microflow is executed in the same context as the page (client) that the user is seeing. For example if there is a button on the page that triggers a microflow that refreshes the client then it will update the widget. However, if the microflow is triggered by the system (e.g. a scheduled event) then these changes are in a different context. Also if another user triggers a refresh it will only refresh that user’s client. Also if one user is logged in through multiple browsers (i.e. has multiple sessions, it also means that for each session there is a different user context.
The simplest solution in this case would likely be to use an appstore widget that periodically triggers a refresh on the object displayed in the dataview, such as this one: https://appstore.home.mendix.com/link/app/27/ . Simply create nanoflow or microflow with a change action that changes no attributes but refreshes the object.

Angular 2 Loader on components and http request

I'm creating an Angular 2 application that uses REST API to retrieve a list of products and a lot of other features.
I want to implement a sort of loader in two ways:
a loader for each component when the page is loaded, for example, when you load the product category page, you will see a spinner over an overlay that load until the http request and the render is finished.
the same thing when you click for example "add to cart" i want to create an overlay over the product column that disable for a few second clicking again on the add to cart button until the product is added to cart.
How can I do this?
Thanks in advance!
i've founded a sort of solution on the net.
It's this: https://www.npmjs.com/package/angular2-busy
And i'm able to manage the loader on a http request.
It's easy to use and you can applicate this 'busy' loader on Promises and Observable's subscription.
Hope it helps.
You can add a loader for each component when the page is loaded in a simple way. Just add a a loader gif inside the component tag. It will be replaced with the data from the component when component has recived the data from the REST-API.
ex: <mycomponent><img src="spinner.gif"></mycomponent>
For the second part, "add to cart". You should be able to add a css-class to the product column with the overlay, triggered when you click "add to cart".
Call the API and add the product, in the subscription for the HTTP observable, you can set a "callback" method to be called when the operation is complete, in your case close the overlay.

Query regarding response of Mixpanel.track event

Suppose I have different cards, or section in a page with “like” button on every card. On clicking this card, a Mixpanel “like” event is fired with some custom properties – Button Name, Card/Section name etc.
Question –
Now if I want to show the count of “like” on every card, in real – time, how can we do that. An example is – if the user clicks like on a card, the count of like for the card will increment without refreshing the page. Will it be possible to get the response of “mixpanel.track” event and in response fetch the count of “like” event and display below every card.
Currently I am using below mentioned API URL which is returning list of all entries for the specified event and property.
URL – https://mixpanel.com/api/2.0/events/properties/?name=Name of property&event=Name of Event&type=general&unit=month"
you can use the callback in mixpanel.track
https://mixpanel.com/help/reference/javascript-full-api-reference#mixpanel.track
One more thing you should do is use mixpanel.increment so like count gets stored in mixpanel as well
https://mixpanel.com/help/reference/javascript-full-api-reference#mixpanel.people.increment
Hope this helps,
Che

ion-nav-back-button not firing state controller

So, I am using ui-router for my app's routing. There is a scenario, I clicked like button on the item detail page. Then I hit back button, it goes back to the main page, it is a list of items. The item has a likes counter. But I found the counter did not increase because back button did not fire the controller for main page.
I want to understand how can I fire the controller while clicking back button.
You should isolate your data in a provider to manage the data sync between your views. If all of the data is contained in a service, you can update it from one view, and it will always be synced with the other.
In both of the controllers, require 'ItemRepository' which will provide the data to the views.

AngularJS - removing the line between SPA and AJAX data binding

In Angular, speed is the name of the game and rendering views with useful data as quickly as possible is always sought after. Angular allows us to reference data between the Controller and the View seamlessly using Angular's templating engine, which can make rendering views with correctly bound data lightning fast.
For example, lets say we have a simple Angular App which is simply a table of contacts with fields like First Name, Last Name, Phone, Email, and Address. We then want a Details view that appears when you click on a table row. We can wire up the <tr> to change views on click like this
<tr ng-repeat="contact in Contacts" ng-click="showDetails(contact)">
Then we can change the view and "instantly" show contact data in the new view. For example, we can change an <h1> at the top of the page to be Contact - John Smith using the data that was provided in showDetails.
While this data is being shown, more data can be retrieved from the server asynchronously that will then fill in the rest of the fields.
However, what do we do if we want to get to this details page directly from the url? If the contact table was sitting at /contacts and the details page was something like /contacts/detail/1 then attempting to go directly to /contacts/detail/1 would result in the <h1> above to be blank.
This is clearly because we did not use the showDetails() method to invoke the view and pass the clicked contact into it directly. In this case, we would need to take the contact id in the URL and run an AJAX request to get ALL of the data.
My question is, at what point do we draw the line between trying to make our views and data quickly accessible and making them robust?
Robust is a must.
So we need to start there. Then we can move forward to optimize and make data "quickly accessible", as you put it, as much as possible.
In order to do that, every view in an SPA that is directly correlated to a URL needs to be initially stateless. That basically means that a reload on any url will load the desired view correctly and completely.
We can get the best of both worlds by using nested routes. If every route loads only what it needs, but also draws on parent routes (loading them if necessary, or just using them if they have already been provided) then you can achieve both robustness and "quick accessibility" to data.
In your particular example, the base route would be contacts. Then there could be a nested route inside of that which would display the details of a particular contact, contacts/detail/{id}. Loading the base url would load the list of contacts, and loading the details view would load both the list of contacts and the details of a particular contact. To provide quickly accessible data when going to the nested view, we could include logic that checks to see if the parent view data is already loaded, and only load if necessary. Then when navigating from the contacts to the contacts/detail/{id} view, we could quickly display data from the parent view in the child view, while loading data specific to the child view. A reload at contacts/detail/{id} would simply load both. When navigating back to the parent, the parent data would already be loaded.
If you were to use something like ui-router to create complex routes, then you would not use showDetails() to alter the model, you would use showDetails() to alter the route. Then your model would set itself up based on the route, and your view would follow.
For example, you could have something like:
$scope.showDetails = function(contact) {
$state.go('contacts.detail', { contactId: contact.id });
};
Then the controller could use $stateParams to retrieve any data you wanted for the specific contact from the server (asynchronously using promises). You could also include your own flavour of caching/loading via services to manage things like performance if you found it necessary.

Resources