Vue JS - Data not updating reactively - javascript

I have a pagination indicator that shows the number of results on a given page, for example; page 1 would show '1-5' and page 2 shows '6-10 out of 50 results' etc.
I have set the logic in place and it appears to be working, however for the results to update on any other page except for page 1, I would have to refresh the page every time. Therefore '1-5' always appears. I'm still learning vue and I'm sure it must be some silly mistake here.
What can I do to have the results update when I change page?
Pagination.vue
<!-- Results counter -->
<PaginationResultIndicator :total-items="paginationData.totalItems"
:first-item="firstItem"
:last-item="lastItem"/>
// Script
data: () => ({
currentPage: -1,
limit: undefined,
firstItem: undefined,
lastItem: undefined
}),
created() {
this.currentPage = this.paginationData.current;
this.limit = this.paginationData.totalItems / this.paginationData.totalPages
this.lastItem = this.limit * this.paginationData.current;
this.firstItem = this.lastItem - this.limit + 1;
},

Your should replace data:() =>{... to data(){...}
https://v2.vuejs.org/v2/style-guide/index.html#Component-data-essential

Related

My React function gets called twice, with the second call setting values incorrectly

i have a function that calculates pages and page buttons based on an api. Inside the buttons get rendered and they have an onClick function. When i click the button, this is supposed to happen:
sets the current page number and writes it into state
calls the api which gets text elements to display according to current page
evaluates page buttons and numbers based on api and marks the current page with a css class
event handler:
handleClick(event) {
let currentPage = Number(event.target.id)
localStorage.setItem("currentPage", currentPage)
this.setState ({
currentPage: currentPage
})
this.fetchApi()
}
then i'm returning the component that deals with pages:
return(
<div>
<Paging
data = {this}
currentPage = {this.state.currentPage}
state = {this.state}
lastPage = {this.state.lastPage}
handleClick = {this.handleClick}
/>
</div>
)
and the component looks like this:
function Paging(props) {
const apiPaging = props.state.apiPaging
const apiPagingSliced = apiPaging.slice(1, -1)
const renderPageNumbers = apiPagingSliced.map((links, index) => {
return <button key={index} id={links.label}
onClick={(index)=>props.handleClick(index)}
className={(links.active ? "mark-page" : "")}
>{links.label} {console.log(links.label) }
</button>
})
return (
<div id = "page-nums">
{renderPageNumbers}
</div>
)
So what happens is that Paging() function gets called twice. There is a handy value inside the api called "active" (links.active) which is a boolean, and if set to true, means that the page is the current page. i then add a class "mark-page" on to highlight that i'm currently on that page. If i {console.log(links.label)} i see that it's invoked twice, first being the correct values and second being the previously clicked values. So it works correctly only if i reload the page again.
i.e if i click page 2,it stays on page 1 and marks page 1. if i then click page 3, it marks page 2. and (afaik) Paging() gets only invoked once, at the end of my only class (Body).
I've been at it yesterday and today and have no idea anymore.
change your handleClick function to this.
handleClick(event) {
window.scrollTo({
top: 0,
behavior: 'smooth',
});
if (event.target.id >= 1) {
let currentPage = Number(event.target.id);
localStorage.setItem('currentPage', currentPage);
this.setState({
currentPage: JSON.parse(localStorage.getItem('currentPage')),
},()=>{
this.fetchApi();
});
}
}
in your fetchApi function you reference currentPage as below.
const apiQuery = JSON.parse(this.state.currentPage);
But it hasn't updated yet.
see https://reactjs.org/docs/react-component.html#setstate

Ion RangeSlider not reloading correctly in Angular 9 project

I am trying to integrate Ion.RangeSlider into an Angular 9 project to select a range of dates. I'm having an issue where the slider works when it initially loads on a page; however it doesn't load right when I navigate back to the same page.
(Edited to add routes)
For example, here is a view when I load a page in my project (/#/category?id=13&data_list_id=15), and the slider is loading as expected:
The next tab over navigates to (/#/category?id=13&data_list_id=16) also generates the slider as expected:
Returning to the initial summary view (/#/category?id=13&data_list_id=15) results in the slider appearing as an input box and not working properly.
Below are sections of code from my component that I think are the relevant parts to generating the slider.
date-slider.component.html
<label [for]="'dateFrom'" class="visuallyhidden">Date From:</label>
<input type="text" [name]="'dateFrom'" [id]="'dateFrom'" [value]="sliderDates[start]" class="date-input js-from" />
<div class="slider-container">
<input class="sliders" type="text" [id]="'slider'" value="" aria-label="date-range-slider" />
</div>
<label [for]="'dateTo'" class="visuallyhidden">Date To:</label>
<input type="text" [name]="'dateTo'" [id]="'dateTo'" [value]="sliderDates[end]" class="date-input js-to" />
date-slider.component.ts
ngOnInit() {
if (this.dates && this.dates.length) {
const defaultRanges = this.findDefaultRange(this.dates, this.freq, this.defaultRange, this.dateFrom, this.dateTo);
// Start and end used for 'from' and 'to' inputs in slider
// If start/end exist in values array, position handles at start/end; otherwise, use default range
this.start = defaultRanges.start;
this.end = defaultRanges.end;
this.sliderDates = defaultRanges.sliderDates; // Array of dates for the slider i.e. ['2000', '2001', '2002', '2003', '2004', '2005']
}
}
ngAfterViewInit() {
const $fromInput = $(`#dateFrom`);
const $toInput = $(`#dateTo`);
const $range = $(`#slider`).data('ionRangeSlider');
this.initRangeSlider(this.sliderDates, this.start, this.end, this.freq);
// Set change functions for 'from' and 'to' date inputs
this.setInputChangeFunction($fromInput, this.sliderDates, $range, 'from', this.portalSettings, this.freq);
this.setInputChangeFunction($toInput, this.sliderDates, $range, 'to', this.portalSettings, this.freq);
this.updateChartsAndTables($fromInput.prop('value'), $toInput.prop('value'), this.freq)
this.cd.detectChanges(); // cd refers to ChangeDetectorRef
}
initRangeSlider(sliderDates: Array<any>, start: number, end: number, freq: string) {
const updateChartsAndTables = (from, to, freq) => this.updateChartsAndTables(from, to, freq);
const $fromInput = $(`#dateFrom`);
const $toInput = $(`#dateTo`);
$(`#slider`).ionRangeSlider({
min: 0,
from: start,
to: end,
values: sliderDates,
prettify_enabled: false,
hide_min_max: true,
hide_from_to: true,
keyboard: true,
keyboard_step: 1,
skin: 'round',
type: 'double',
onChange: function (data) {
$fromInput.prop('value', data.from_value);
$toInput.prop('value', data.to_value);
},
onFinish: function (data) {
updateChartsAndTables(data.from_value, data.to_value, freq);
}
});
}
I have tried using the ng2-ion-range-slider wrapper, but I end up with the following error when I load it into my module:
This likely means that the library (ng2-ion-range-slider) which declares IonRangeSliderModule has not been processed correctly by ngcc, or is not compatible with Angular Ivy. Check if a newer version of the library is available, and update if so. Also consider checking with the library's authors to see if the library is expected to be compatible with Ivy.
(Weirdly the slider works fine on an existing project that is basically the same application. The existing application was developed back when Angular was at version 2. It became a multiple app project where all the components, services, and individual app modules were all in the same src folder. But now that Angular-cli supports generating multiple apps in the same project, I'm trying to split things up and keep reusable/common components in their own custom library.)

Primeng paginator cannot reset page 1 after call API

I have 2 functions to load data: when init page and search page.
When init page, the data display with 5 pages. I click page 3, the data show with paging is Ok. After that, enter data search. The data table is reload, but the page number does not reset to 1, it's still page 3.
in html:
<p-paginator rows="5" totalRecords="{{totalRecords}}" (onLazyLoad)="paginate($event)"
(onPageChange)="paginate($event)" [rowsPerPageOptions]="[2,5,10,20]"></p-paginator>
ts:
defaultPage:0;
defaultSize:2
paginate(event) {
let currentPage: number;
this.defaultPage = event.first / event.rows;
this.defaultSize = event.rows;
this.listData = [];
if (this.isSearch == 1) {
this.getLoadPageSearch(this.defaultSize, this.defaultPage);
} else {
this.getLoadPage(this.defaultSize, this.defaultPage);
}
}
Please adivice me how to reset the paginator after call another API
The p-paginator component contains the changePageToFirst function. To access this function, we will need to obtain a ViewChild reference to the component. For example, in our template we define the component:
<p-paginator rows="10" totalRecords="100" #p></p-paginator>
<button (click)="reset($event)">Reset</button>
And in our component, we can handle the reset event as follows:
#ViewChild('p', {static: false}) paginator: Paginator;
reset($event) {
this.paginator.changePageToFirst($event);
}
Here is a demo: https://plnkr.co/edit/FxwTHK0W2WuTCjuqhLp6?p=preview
EDIT: The above demo is no longer working on plunkr. Here is an updated version:
https://stackblitz.com/edit/angular-u9nqf5
Another useful method is changePage.
In template:
<p-paginator #pp></p-paginator>
In the component:
#ViewChild('pp') paginator: Paginator;
this.paginator.changePage(0);
For those using the dataTable primeng component and using its lazy pagination feature,
we can reset the page to '1' by using
this.tableTemplateName.first = 0;
where setting first=0 means first page

Polymer back button doesn't work with hash routing

Sup! Back button sometimes doesn't work with my polymer project. When i hit back button the page variable is steel the current page and i need to hit the button twice or three times to get it working for example i go to the /#/rules page from /#/home but it doesn't go back to /#/home once i press the back button the second or third time by the way it does go back to the main page. Here is my observer and router:
properties: {
page: {
type: String,
reflectToAttribute: true,
observer: '_pageChanged',
},
},
observers: [
'_routePageChanged(routeData.page)',
],
_routePageChanged: function (page) {
this.page = page || 'home';
this.set('route.path', `/${this.page}`);
},
_pageChanged: function (page) {
// Load page import on demand. Show 404 page if fails
var resolvedPageUrl = this.resolveUrl(page + '.html');
this.importHref(resolvedPageUrl, null, this._showPage404, true);
window.history.pushState({}, null, `#/${this.page}`);
},
And this is my app-route element:
<app-route route="{{route}}" pattern="/:page" data="{{routeData}}" tail="{{subroute}}"></app-route>
Just can't figure out why it does not work the first time. Any help is appreciated and i have already searched a lot with no results.
Can you try this, assuming you have <app-route route="{{route}}"></app-route>?
observers: [
'_routePageChanged(route.path)',
],
_routePageChanged: function(path) {
if (path) {
this.page = this.routeData.page;
} else {
/*
* It's unnecessary to have the following line.
*/
// this.page = 'home';
this.set('route.path', '/home');
}
},
Why it works after all?
I learned my lesson by debugging the source code of <app-route>. If the path is empty, the code for updating data will be skipped - and your observer, _routePageChanged(routeData.page), won't be triggered. See
https://github.com/PolymerElements/app-route/blob/master/app-route.html#L254-L257
https://github.com/PolymerElements/app-route/blob/master/app-route.html#L320-L328
You may consider it to be a flaw in <app-route>. Whatsoever, it's open source, and you can always find your way.

jQuery jTable pagination is not working properly

I'm using jquery jTable in my web-based project. Its pagination work fine when the number of rows less than 10,000. But when the number of rows exceeded from 10000, it causes an unfamiliar issue in its pagination. The pagination start skipping odd page numbering. You can see it in picture below:
My javaScript code for jTable is:
$("#AllProductTable").jtable({
paging: true,
pageSize: 10,
columnSelectable: false,
actions: {
listAction: '/ProductDefinition/Select'
},
fields: {
ProductId: { visibility: 'hidden', listClass: 'right-align' },
ProductCode: { title: 'Product Code' },
// more fields...
},
recordsLoaded: function (event, data) {
}
});
while my html tag for jTable is:
<div id="AllProductTable" style="width:400%;"></div>
I explored a lot\, but didn't find the solution related to it. I'm further unable to understand this miss behavior.
And at last, I got succeeded to solve this issue. I go through the jquery.jtable.js whole file and find something strange in one of its function. The function was;
_refreshGotoPageInput: function() {
// different logic statements
//...
//Skip some pages is there are too many pages
var pageStep = 1;
if (currentPageCount > 10000) { // if you having more than 10,000 pages
pageStep = 100;
} else if (currentPageCount > 5000) { // if you having more than 5000 pages
pageStep = 10;
} else if (currentPageCount > 2000) { // if you having more than 2000 pages
pageStep = 5;
} else if (currentPageCount > 1000) { // if you having more than 1000 pages
pageStep = 2;
}
//....
// Differnet logic statements
}
All you need is just to comment this portion of the above given function, or modify it according to your own implementation logic.
In my above mentioned case, my no_of_pages were increasing from 1000, that's why its taking 2-steps on changing page and so on.

Categories