Vue.js merge data without a re-render? - javascript

I have a search component that gets its data in the form as a prop of PHP json_encoded data:
<search :data="<?= json_encode($jsonHotels) ?>"></search>
This way it receives the first 25 movies straight away when the page renders.
After this I make an ajax request to fetch the rest of the result if there are more than 25 movies.
The problem is that when I override the data with the data from the AJAX call, the component re-renders.
Previously to combat this I performed an ajax request with an offset of 25 to skip the first 25 movies and only give me the extra results. Pushing this onto the array didn't cause a re-render and this worked perfectly.
That was perfect, until I got to thinking:
What about people who start or refresh the page while they are on page number 2-3-4-5-etc.
I now have to not only mess with my offset, but I also have to possibly prepend data to my array and well as possibly append data with a push.
Is there a way to merge data without causing a re-render? I am wondering if anyone else has every run into the problem.
Simply fetching all results with an AJAX request takes too long and obviously also causes a re-render. Not fetching initial backend data would mean people would be starting at a blank page or a spinner for 2-3 seconds.
Edit:
Ended up with this:
mergeData(state) {
// Smart merge ajaxData and hotels.
const offSet = state.currentPage * state.itemsPerPage;
const start = state.ajaxData.slice(0, offSet - state.itemsPerPage);
const end = state.ajaxData.slice(offSet);
state.data.unshift(...start);
state.data.push(...end);
},
Pretty much slice my array in 2 and remove the currentPage section. By using unshift and push I prevent a re-render from happening.

Remember that your viewmodel is a model of your view. Here, you're not modeling your application, you're just trying to plug your data in.
If you want to display a page of results at a time, have some kind of model for a page of results. When you fetch your data, put it into the appropriate model-pages. Since you're only displaying one page at a time, populating other pages will not cause a re-render.

Related

How to get data after 10 data skip in Realtime database firebase javascript node js

I am using Node js with Express.js and I am getting data from firebase's real-time database
so How can I get data after 10 children or nodes by skipping?
example
I have a lot of data like -
Images
imageId
- {some properties ie: imgUrl:"somevalue.jpg"}
and more
So first I am taking first 10 images using limitFirst(10) function.
and if the user clicks on link or next button I want to load the next first 10 images if available
does firebase real-time database have some functionality like this
//limitToAfter(afterChild, limit);
const imageRef = query("Images", limitToAfter(10,10));
onValue(imageRef,(snapshot)=>{
//some operation here...
});
Or can anyone give me some ways I can solve this problem?
I will always appreciate any help :)
Firebase Realtime Database doesn't have an offset mechanism. Instead to get the next page of data, you need to know the last node on the current page.
For example, say that the key of the last item on page 1 is "key10", then you can get the next 10 items with:
query("Images", orderByKey(), startAfter("key10"), limitToFirst(10));
In words: take all nodes under Images, order them by their key, then start after "key10" and return the first 10 nodes.

Suggestions on how to deal with this model constantly being re-initialized in a set interval?

I have been recently assigned to maintain EmberJS code at work and I am complete newbie with EmberJS or Javascript, Hence, I came here for help.
Context
I have a live feed page (like a news feed) that is integrated with Infinity Loading and this feed constantly checks with the backend to see for any new messages. This is causing this code to be constantly invoked.
import InfinityRoute from "ember-infinity/mixins/route";
export default Ember.Route.extend(InfinityRoute,{
perPageParam: "perPage",
totalPagesParam: "meta.totalPages",
queryParams: { dateFrom:.... },
model(params){
const defaultParams = { perPage: 25, startingPage: 1 } ;
const modelParams = Ember.$.extend(defaultParams, params);
return this.infinityModel("message", modelParams);
}
The above code will load 25 pages with startingPage as 1 and pass it to the infinityModel which will contact the data store to get the necessary information.
Question Scenario
Above code is constantly bringing you back to page 1 and lose track of the current page
(Example, If you scroll above 25 messages and are in the 2nd page, then the 2nd page keeps disappearing and re-appearing because of the scroll position and model re-initialization setting the startingPage back to 1)
I would love if you guys can provide me with any suggestions on how to handle this model re-initialization and infinityScroll issue?
I'm not sure if I understand your problem correctly but likely we had to solve similar problem. Our backend periodically rewrites model that is used to generate recursive components. These components have some state information that was loose after each model reload. We had decided to solve this using Ember.ArrayProxy.
You want to record 'live-array' where changes will be sent to templates, like when you are using store.findAll() - on other side store.peekAll() returns standard array.

GridX clear the sort without making new request

I am using GridX to display data, but I often change the data store that the GridX is using. I do this by using grid.setStore() and pass in a Dojo JsonStore (this is asynchronous data of course). I do not recreate the grid every time I change the data store, just call setStore(), then refresh().
The grid also has the NestedSort module activated. My problem is this:
If the user sorts on a store, and then chooses a set of different data to look at, the code calls:
grid.sort.clear();
grid.setStore( /* new store*/ );
grid.refresh();
Without .clear() being called, the grid will try to sort the new store of data (which is usually invalid, and throws a 500).
With .clear(), the store will make a call to the server to sort the first data store, before then calling for a fresh batch of the next data store.
Ideally I want to tell the grid to clear any sort preference before I grab the next set of data, so that it is not attempting to sort it. I do not want it to make an additional call to sort the first data immediately before it gets replaced.
I finally worked it out. To clear the sort information in the grid you must modify the grid model. The sorting in the grid model can be done using this:
grid.model.sort();

search items that load data from DB in Knockout JS

In my application, I have an observableArray that loads data from DB. This observableArray fills first 25 items from DB and from scrolled down it loads another 25 and it goes on.
Now, I want to implement search, that should display the result searching the whole data from DB and not just from the displayed 25 items.
I tried to get the search result by sending the whole searching text to DB on clicking search button and there is lot of datas in DB which takes much time to load data.
Please let me know how I can get the desired result from DB within ms. Thanks in advance.
To get a well behaving search with Knockout, you should extend your searchText observable that is bound to the input with a rate-limiter
this.searchText = ko.observable('').extend({ rateLimit: { timeout: 500, method: "notifyWhenChangesStop" } })
This will call any subscribers after the input has remained unchanged for 500ms (i.e. when the user stops typing). You could also use the default method notifyAtFixedRate to call the API at least once every X seconds.
And to top it off, a fiddle!
Note: with this being said, if your query is taking 40 seconds, that sounds like a problem with your database query. It's possible that it's taking that long because you're flooding the server with requests, but that still seems awfully slow. This is the strategy we use and it works excellent, but our API response time is <200ms.

Reactjs - getting data from server and updating

(reactjs newbie here)...
I'm using Reactjs to create a page where I have
a simple search box
user types in a search text
data is fetched from the server and is displayed
Now, the "searchText" and "data" are my states and I'm trying to figure out how to update the "results" only after the data is received from the server.
I have an event where I handle whenever user types something as a search text
handleUserInput: function(searchText) {
this.loadDataFromServer(searchText);
this.setState({
searchText: searchText,
});
},
But with the above function, the following thing happens
Initial data is loaded
User types in something
The result is IMMEDIATELY updated to only show the the result that contains the search text (code below), BUT at the same time a request is made to the server to fetch results where the result contains the search text
this.props.products.forEach(function(product) {
if(product.name.toLowerCase().indexOf(this.props.searchText) > -1) {
row =
rows.push(row)
}
}.bind(this));
After about a second, new data is received from the server and the result is refreshed again.
Obviously what I want to do is
Load initial data
User types search text
Request data from the server
Receive data from the server
Update the results
What is the proper way of achieving this?
Don't think searchText should be a state itself. You could just use data fetched from the server to set the state.
Let's say, data is a state property. you could pass a callback to the loadDataFromServer and loadDataFromServer calls this callback once data is fetched on it's onsuccess.
this.loadDataFromServer(searchText, function(data) {
this.setState({data: data}};
});
This way, the component will rerender and show the results, once the data is updated.
So, it is just the first refresh that you want to stop right?
If it is already refreshing once the results come from the server, it seems that all you need to do is not filter the results on the client in step 3 - then the same virtual DOM will be generated as in the first place, so the result list will only update the actual DOM once the server responds.

Categories

Resources