LP#1775466 ng-lint updates
authorBill Erickson <berickxx@gmail.com>
Fri, 18 May 2018 21:38:14 +0000 (17:38 -0400)
committerBill Erickson <berickxx@gmail.com>
Wed, 6 Jun 2018 20:59:40 +0000 (16:59 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/share/grid/grid.ts

index 232ad32..2d8af79 100644 (file)
@@ -3,7 +3,7 @@
  */
 import {TemplateRef} from '@angular/core';
 import {Observable} from 'rxjs/Observable';
-import {Subscription} from "rxjs/Subscription";
+import {Subscription} from 'rxjs/Subscription';
 import {EgIdlService, EgIdlObject} from '@eg/core/idl.service';
 import {EgOrgService} from '@eg/core/org.service';
 import {EgStoreService} from '@eg/core/store.service';
@@ -12,6 +12,243 @@ import {Pager} from '@eg/share/util/pager';
 
 const MAX_ALL_ROW_COUNT = 10000;
 
+export class EgGridColumn {
+    name: string;
+    path: string;
+    label: string;
+    flex: number;
+    align: string;
+    hidden: boolean;
+    visible: boolean;
+    sort: number;
+    idlClass: string;
+    idlFieldDef: any;
+    datatype: string;
+    cellTemplate: TemplateRef<any>;
+    isIndex: boolean;
+    isDragTarget: boolean;
+    isSortable: boolean;
+    isMultiSortable: boolean;
+}
+
+export class EgGridColumnSet {
+    columns: EgGridColumn[];
+    idlClass: string;
+    indexColumn: EgGridColumn;
+    isSortable: boolean;
+    isMultiSortable: boolean;
+    stockVisible: string[];
+
+    constructor(idlClass?: string) {
+        this.columns = [];
+        this.stockVisible = [];
+        this.idlClass = idlClass;
+    }
+
+    add(col: EgGridColumn) {
+        // avoid dupes
+        if (this.getColByName(col.name)) { return; }
+
+        if (col.isIndex) { this.indexColumn = col; }
+        if (!col.flex) { col.flex = 2; }
+        if (!col.label) { col.label = col.name; }
+        if (!col.align) { col.align = 'left'; }
+        if (!col.datatype) { col.datatype = 'text'; }
+
+        col.visible = !col.hidden;
+
+        // track which fields are visible on page load.
+        if (col.visible) {
+            this.stockVisible.push(col.name);
+        }
+
+        this.applyColumnSortability(col);
+
+        this.columns.push(col);
+    }
+
+    getColByName(name: string): EgGridColumn {
+        return this.columns.filter(c => c.name === name)[0];
+    }
+
+    reset() {
+        this.columns.forEach(col => {
+            col.flex = 2;
+            col.sort = 0;
+            col.align = 'left';
+            col.visible = this.stockVisible.includes(col.name);
+        });
+    }
+
+    applyColumnSortability(col: EgGridColumn) {
+        // column sortability defaults to the sortability of the column set.
+        if (col.isSortable === undefined && this.isSortable) {
+            col.isSortable = true;
+        }
+
+        if (col.isMultiSortable === undefined && this.isMultiSortable) {
+            col.isMultiSortable = true;
+        }
+
+        if (col.isMultiSortable) {
+            col.isSortable = true;
+        }
+    }
+
+    displayColumns(): EgGridColumn[] {
+        return this.columns.filter(c => c.visible);
+    }
+
+    insertBefore(source: EgGridColumn, target: EgGridColumn) {
+        let targetIdx = -1;
+        let sourceIdx = -1;
+        this.columns.forEach((col, idx) => {
+            if (col.name === target.name) { targetIdx = idx; }});
+
+        this.columns.forEach((col, idx) => {
+            if (col.name === source.name) { sourceIdx = idx; }});
+
+        if (sourceIdx >= 0) {
+            this.columns.splice(sourceIdx, 1);
+        }
+
+        this.columns.splice(targetIdx, 0, source);
+    }
+
+    // Move visible columns to the front of the list.
+    moveVisibleToFront() {
+        const newCols = this.displayColumns();
+        this.columns.forEach(col => {
+            if (!col.visible) { newCols.push(col); }});
+        this.columns = newCols;
+    }
+
+    moveColumn(col: EgGridColumn, diff: number) {
+        let srcIdx, targetIdx;
+
+        this.columns.forEach((c, i) => {
+          if (c.name === col.name) { srcIdx = i; }
+        });
+
+        targetIdx = srcIdx + diff;
+        if (targetIdx < 0) {
+            targetIdx = 0;
+        } else if (targetIdx >= this.columns.length) {
+            // Target index follows the last visible column.
+            let lastVisible = 0;
+            this.columns.forEach((c, idx) => {
+                if (c.visible) { lastVisible = idx; }
+            });
+
+            // When moving a column (down) causes one or more
+            // visible columns to shuffle forward, our column
+            // moves into the slot of the last visible column.
+            // Otherwise, put it into the slot directly following
+            // the last visible column.
+            targetIdx = srcIdx <= lastVisible ? lastVisible : lastVisible + 1;
+        }
+
+        // Splice column out of old position, insert at new position.
+        this.columns.splice(srcIdx, 1);
+        this.columns.splice(targetIdx, 0, col);
+    }
+
+    compileSaveObject(): EgGridColumnPersistConf[] {
+        // only store information about visible columns.
+        const conf = this.displayColumns();
+
+        // scrunch the data down to just the needed info
+        return conf.map(col => {
+            const c: EgGridColumnPersistConf = {name : col.name};
+            if (col.align !== 'left') { c.align = col.align; }
+            if (col.flex !== 2) { c.flex = Number(col.flex); }
+            if (Number(col.sort)) { c.sort = Number(c.sort); }
+            return c;
+        });
+    }
+
+    applyColumnSettings(conf: EgGridColumnPersistConf[]) {
+        if (!conf || conf.length === 0) { return; }
+
+        const newCols = [];
+
+        conf.forEach(colConf => {
+            const col = this.getColByName(colConf.name);
+            if (!col) { return; } // no such column in this grid.
+
+            col.visible = true;
+            if (colConf.align) { col.align = colConf.align; }
+            if (colConf.flex)  { col.flex = Number(colConf.flex); }
+            if (colConf.sort)  { col.sort = Number(colConf.sort); }
+
+            // Add to new columns array, avoid dupes.
+            if (newCols.filter(c => c.name === col.name).length === 0) {
+                newCols.push(col);
+            }
+        });
+
+        // columns which are not expressed within the saved
+        // configuration are marked as non-visible and
+        // appended to the end of the new list of columns.
+        this.columns.forEach(c => {
+            if (conf.filter(cf => cf.name === c.name).length === 0) {
+                c.visible = false;
+                newCols.push(c);
+            }
+        });
+
+        this.columns = newCols;
+    }
+}
+
+
+export class EgGridRowSelector {
+    indexes: {[string: string]: boolean};
+
+    constructor() {
+        this.clear();
+    }
+
+    // Returns true if all of the requested indexes exist in the selector.
+    contains(index: string | string[]): boolean {
+        const indexes = [].concat(index);
+        for (let i = 0; i < indexes.length; i++) { // early exit
+            if (!this.indexes[indexes[i]]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    select(index: string | string[]) {
+        const indexes = [].concat(index);
+        indexes.forEach(i => this.indexes[i] = true);
+    }
+
+    deselect(index: string | string[]) {
+        const indexes = [].concat(index);
+        indexes.forEach(i => delete this.indexes[i]);
+    }
+
+    // Returns the list of selected index values.
+    // in some contexts (template checkboxes) the value for an index is
+    // set to false to deselect instead of having it removed (via deselect()).
+    selected() {
+        return Object.keys(this.indexes).filter(
+            ind => Boolean(this.indexes[ind]));
+    }
+
+    isEmpty(): boolean {
+        return this.selected().length === 0;
+    }
+
+    clear() {
+        this.indexes = {};
+    }
+}
+
+
+
 export class EgGridContext {
 
     pager: Pager;
@@ -62,7 +299,7 @@ export class EgGridContext {
         this.getColumnsConfig(this.persistKey)
         .then(conf => this.columnSet.applyColumnSettings(conf))
         .then(ok => this.dataSource.requestPage(this.pager))
-        .then(ok => this.listenToPager())
+        .then(ok => this.listenToPager());
     }
 
     destroy() {
@@ -77,21 +314,23 @@ export class EgGridContext {
 
     // Subscribe or unsubscribe to page-change events from the pager.
     listenToPager() {
-        if (this.pageChanges) return;
+        if (this.pageChanges) { return; }
         this.pageChanges = this.pager.onChange$.subscribe(
             val => this.dataSource.requestPage(this.pager));
         // TODO: index rows as they arrive
     }
 
     ignorePager() {
-        if (!this.pageChanges) return;
+        if (!this.pageChanges) { return; }
         this.pageChanges.unsubscribe();
-        this.pageChanges = null
+        this.pageChanges = null;
     }
 
     getRowIndex(row: any): any {
-        let col = this.columnSet.indexColumn;
-        if (!col) throw new Error('grid index column required');
+        const col = this.columnSet.indexColumn;
+        if (!col) {
+            throw new Error('grid index column required');
+        }
         return this.getRowColumnValue(row, col);
     }
 
@@ -100,35 +339,39 @@ export class EgGridContext {
     getRowPosition(index: any): number {
         // for-loop for early exit
         for (let idx = 0; idx < this.dataSource.data.length; idx++) {
-            if (index == this.getRowIndex(this.dataSource.data[idx]))
+            if (index === this.getRowIndex(this.dataSource.data[idx])) {
                 return idx;
+            }
         }
     }
 
     getRowByIndex(index: any): any {
         for (let idx = 0; idx < this.dataSource.data.length; idx++) {
-            if (index == this.getRowIndex(this.dataSource.data[idx]))
+            if (index === this.getRowIndex(this.dataSource.data[idx])) {
                 return this.dataSource.data[idx];
+            }
         }
     }
 
     // Returns all selected rows, regardless of whether they are
     // currently visible in the grid display.
     getSelectedRows(): any[] {
-        let selected = [];
+        const selected = [];
         this.rowSelector.selected().forEach(index => {
-            let row = this.getRowByIndex(index);
-            if (row) selected.push(row);
+            const row = this.getRowByIndex(index);
+            if (row) {
+                selected.push(row);
+            }
         });
         return selected;
     }
 
     getRowColumnValue(row: any, col: EgGridColumn): string {
         let val;
-        if (typeof row[col.name] == 'function') {
+        if (typeof row[col.name] === 'function') {
             val = row[col.name]();
         } else {
-            val = row[col.name]
+            val = row[col.name];
         }
         return this.format.transform({value: val, datatype: col.datatype});
     }
@@ -160,14 +403,16 @@ export class EgGridContext {
     }
 
     selectRowByPos(pos: number) {
-        let row = this.dataSource.data[pos];
-        if (row) this.selectOneRow(this.getRowIndex(row));
+        const row = this.dataSource.data[pos];
+        if (row) {
+            this.selectOneRow(this.getRowIndex(row));
+        }
     }
 
     selectPreviousRow() {
-        if (!this.lastSelectedIndex) return;
-        let pos = this.getRowPosition(this.lastSelectedIndex);
-        if (pos == this.pager.offset) {
+        if (!this.lastSelectedIndex) { return; }
+        const pos = this.getRowPosition(this.lastSelectedIndex);
+        if (pos === this.pager.offset) {
             this.toPrevPage().then(ok => this.selectLastRow(), err => {});
         } else {
             this.selectRowByPos(pos - 1);
@@ -175,9 +420,9 @@ export class EgGridContext {
     }
 
     selectNextRow() {
-        if (!this.lastSelectedIndex) return;
-        let pos = this.getRowPosition(this.lastSelectedIndex);
-        if (pos == (this.pager.offset + this.pager.limit - 1)) {
+        if (!this.lastSelectedIndex) { return; }
+        const pos = this.getRowPosition(this.lastSelectedIndex);
+        if (pos === (this.pager.offset + this.pager.limit - 1)) {
             this.toNextPage().then(ok => this.selectFirstRow(), err => {});
         } else {
             this.selectRowByPos(pos + 1);
@@ -193,7 +438,9 @@ export class EgGridContext {
     }
 
     toPrevPage(): Promise<any> {
-        if (this.pager.isFirstPage()) return Promise.reject('on first');
+        if (this.pager.isFirstPage()) {
+            return Promise.reject('on first');
+        }
         // temp ignore pager events since we're calling requestPage manually.
         this.ignorePager();
         this.pager.decrement();
@@ -202,7 +449,9 @@ export class EgGridContext {
     }
 
     toNextPage(): Promise<any> {
-        if (this.pager.isLastPage()) return Promise.reject('on last');
+        if (this.pager.isLastPage()) {
+            return Promise.reject('on last');
+        }
         // temp ignore pager events since we're calling requestPage manually.
         this.ignorePager();
         this.pager.increment();
@@ -211,7 +460,7 @@ export class EgGridContext {
     }
 
     getAllRows(): Promise<any> {
-        let pager = new Pager();
+        const pager = new Pager();
         pager.offset = 0;
         pager.limit = MAX_ALL_ROW_COUNT;
         return this.dataSource.requestPage(pager);
@@ -219,7 +468,7 @@ export class EgGridContext {
 
     // Returns a key/value pair object of visible column data as text.
     getRowAsFlatText(row: any): any {
-        let flatRow = {};
+        const flatRow = {};
         this.columnSet.displayColumns().forEach(col => {
             flatRow[col.name] =
                 this.getColumnTextContent(row, col);
@@ -232,7 +481,7 @@ export class EgGridContext {
             this.getAllRows().then(ok => {
                 this.dataSource.data.forEach(row => {
                     observer.next(this.getRowAsFlatText(row));
-                })
+                });
                 observer.complete();
             });
         });
@@ -241,7 +490,7 @@ export class EgGridContext {
     gridToCsv(): Promise<string> {
 
         let csvStr = '';
-        let columns = this.columnSet.displayColumns();
+        const columns = this.columnSet.displayColumns();
 
         // CSV header
         columns.forEach(col => {
@@ -249,7 +498,7 @@ export class EgGridContext {
             csvStr += ',';
         });
 
-        csvStr = csvStr.replace(/,$/,'\n');
+        csvStr = csvStr.replace(/,$/, '\n');
 
         return new Promise(resolve => {
             this.getAllRowsAsText().subscribe(
@@ -258,7 +507,7 @@ export class EgGridContext {
                         csvStr += this.valueToCsv(row[col.name]);
                         csvStr += ',';
                     });
-                    csvStr = csvStr.replace(/,$/,'\n');
+                    csvStr = csvStr.replace(/,$/, '\n');
                 },
                 err => {},
                 ()  => resolve(csvStr)
@@ -270,8 +519,8 @@ export class EgGridContext {
     // prepares a string for inclusion within a CSV document
     // by escaping commas and quotes and removing newlines.
     valueToCsv(str: string): string {
-        str = ''+str;
-        if (!str) return '';
+        str = '' + str;
+        if (!str) { return ''; }
         str = str.replace(/\n/g, '');
         if (str.match(/\,/) || str.match(/"/)) {
             str = str.replace(/"/g, '""');
@@ -285,14 +534,16 @@ export class EgGridContext {
         // generate columns for all non-virtual fields on the IDL class
         if (this.columnSet.idlClass) {
             this.idl.classes[this.columnSet.idlClass].fields.forEach(field => {
-                if (field.virtual) return;
-                let col = new EgGridColumn();
+                if (field.virtual) { return; }
+                const col = new EgGridColumn();
                 col.name = field.name;
                 col.label = field.label || field.name;
                 col.idlFieldDef = field;
                 col.datatype = field.datatype;
-                if (field.name == this.idl.classes[this.columnSet.idlClass].pkey)
+                if (field.name ===
+                    this.idl.classes[this.columnSet.idlClass].pkey) {
                     col.isIndex = true;
+                }
                 this.columnSet.add(col);
             });
         }
@@ -300,9 +551,11 @@ export class EgGridContext {
 
 
     saveColumns(): Promise<any> {
-        if (!this.persistKey)
+        if (!this.persistKey) {
             throw new Error('Grid persistKey required to save columns');
-        let compiled: EgGridColumnPersistConf[] = this.columnSet.compileSaveObject();
+        }
+        const compiled: EgGridColumnPersistConf[] =
+            this.columnSet.compileSaveObject();
         return this.store.setItem('eg.grid.' + this.persistKey, compiled);
     }
 
@@ -310,31 +563,12 @@ export class EgGridContext {
     // TODO: saveColumnsAsOrgSetting(...)
 
     getColumnsConfig(persistKey: string): Promise<EgGridColumnPersistConf[]> {
-        if (!persistKey) return Promise.resolve([]);
+        if (!persistKey) { return Promise.resolve([]); }
         return this.store.getItem('eg.grid.' + persistKey);
     }
 
 }
 
-export class EgGridColumn {
-    name: string;
-    path: string;
-    label: string;
-    flex: number;
-    align: string;
-    hidden: boolean;
-    visible: boolean;
-    sort: number;
-    idlClass: string;
-    idlFieldDef: any;
-    datatype: string;
-    cellTemplate: TemplateRef<any>;
-    isIndex: boolean;
-    isDragTarget: boolean;
-    isSortable: boolean;
-    isMultiSortable: boolean;
-}
-
 export class EgGridColumnPersistConf {
     name: string;
     flex?: number;
@@ -342,166 +576,6 @@ export class EgGridColumnPersistConf {
     align?: string;
 }
 
-export class EgGridColumnSet {
-    columns: EgGridColumn[];
-    idlClass: string;
-    indexColumn: EgGridColumn;
-    isSortable: boolean;
-    isMultiSortable: boolean;
-    stockVisible: string[];
-
-    constructor(idlClass?: string) {
-        this.columns = [];
-        this.stockVisible = [];
-        this.idlClass = idlClass;
-    }
-
-    add(col: EgGridColumn) {
-        // avoid dupes
-        if (this.getColByName(col.name)) return;
-
-        if (col.isIndex) this.indexColumn = col;
-        if (!col.flex) col.flex = 2;
-        if (!col.label) col.label = col.name;
-        if (!col.align) col.align = 'left';
-        if (!col.datatype) col.datatype = 'text';
-
-        col.visible = !col.hidden;
-
-        // track which fields are visible on page load.
-        if (col.visible) this.stockVisible.push(col.name);
-
-        this.applyColumnSortability(col);
-
-        this.columns.push(col);
-    }
-
-    getColByName(name: string): EgGridColumn {
-        return this.columns.filter(c => c.name == name)[0];
-    }
-
-    reset() {
-        this.columns.forEach(col => {
-            col.flex = 2;
-            col.sort = 0;
-            col.align = 'left';
-            col.visible = this.stockVisible.includes(col.name);
-        });
-    }
-
-    applyColumnSortability(col: EgGridColumn) {
-        // column sortability defaults to the sortability of the column set.
-        if (col.isSortable === undefined && this.isSortable)
-            col.isSortable = true;
-
-        if (col.isMultiSortable === undefined && this.isMultiSortable)
-            col.isMultiSortable = true;
-
-        if (col.isMultiSortable) col.isSortable = true;
-    }
-
-    displayColumns(): EgGridColumn[] {
-        return this.columns.filter(c => c.visible);
-    }
-
-    insertBefore(source: EgGridColumn, target: EgGridColumn) {
-        let targetIdx = -1;
-        let sourceIdx = -1;
-        this.columns.forEach((col, idx) => {
-            if (col.name == target.name) targetIdx = idx; });
-
-        this.columns.forEach((col, idx) => {
-            if (col.name == source.name) sourceIdx = idx; });
-
-        if (sourceIdx >= 0)
-            this.columns.splice(sourceIdx, 1);
-
-        this.columns.splice(targetIdx, 0, source);
-    }
-
-    // Move visible columns to the front of the list.
-    moveVisibleToFront() {
-        let newCols = this.displayColumns();
-        this.columns.forEach(col => { if (!col.visible) newCols.push(col) });
-        this.columns = newCols;
-    }
-
-    moveColumn(col: EgGridColumn, diff: number) {
-        var srcIdx, targetIdx;
-
-        this.columns.forEach((c, i) => {
-          if (c.name == col.name) srcIdx = i
-        });
-
-        targetIdx = srcIdx + diff;
-        if (targetIdx < 0) {
-            targetIdx = 0;
-        } else if (targetIdx >= this.columns.length) {
-            // Target index follows the last visible column.
-            var lastVisible = 0;
-            this.columns.forEach((c, idx) => {
-                if (c.visible) lastVisible = idx;
-            });
-
-            // When moving a column (down) causes one or more
-            // visible columns to shuffle forward, our column
-            // moves into the slot of the last visible column.
-            // Otherwise, put it into the slot directly following
-            // the last visible column.
-            targetIdx = srcIdx <= lastVisible ? lastVisible : lastVisible + 1;
-        }
-
-        // Splice column out of old position, insert at new position.
-        this.columns.splice(srcIdx, 1);
-        this.columns.splice(targetIdx, 0, col);
-    }
-
-    compileSaveObject(): EgGridColumnPersistConf[] {
-        // only store information about visible columns.
-        let conf = this.displayColumns();
-
-        // scrunch the data down to just the needed info
-        return conf.map(col => {
-            let c: EgGridColumnPersistConf = {name : col.name};
-            if (col.align != 'left') c.align = col.align;
-            if (col.flex != 2) c.flex = col.flex;
-            if (Number(col.sort)) c.sort = Number(c.sort);
-            return c;
-        });
-    }
-
-    applyColumnSettings(conf: EgGridColumnPersistConf[]) {
-        if (!conf || conf.length == 0) return;
-
-        let newCols = [];
-
-        conf.forEach(colConf => {
-            let col = this.getColByName(colConf.name);
-            if (!col) return; // no such column in this grid.
-
-            col.visible = true;
-            if (colConf.align) col.align = colConf.align;
-            if (colConf.flex)  col.flex = colConf.flex;
-            if (colConf.sort)  col.sort = colConf.sort;
-
-            // Add to new columns array, avoid dupes.
-            if (newCols.filter(c => c.name == col.name).length == 0)
-                newCols.push(col);
-        });
-
-        // columns which are not expressed within the saved
-        // configuration are marked as non-visible and
-        // appended to the end of the new list of columns.
-        this.columns.forEach(c => {
-            if (conf.filter(cf => cf.name == c.name).length == 0) {
-                c.visible = false;
-                newCols.push(c);
-            }
-        });
-
-        this.columns = newCols;
-    }
-}
 
 // Actions apply to specific rows
 export class EgGridToolbarAction {
@@ -515,57 +589,12 @@ export class EgGridToolbarButton {
     action: () => any;
 }
 
-export class EgGridRowSelector {
-    indexes: {[string:string] : boolean};
-
-    constructor() {
-        this.clear();
-    }
-
-    // Returns true if all of the requested indexes exist in the selector.
-    contains(index: string | string[]): boolean {
-        let indexes = [].concat(index);
-        for (let i = 0; i < indexes.length; i++) { // early exit
-            if (!this.indexes[indexes[i]])
-                return false;
-        }
-        return true;
-    }
-
-    select(index: string | string[]) {
-        let indexes = [].concat(index);
-        indexes.forEach(i => this.indexes[i] = true);
-    }
-
-    deselect(index: string | string[]) {
-        let indexes = [].concat(index);
-        indexes.forEach(i => delete this.indexes[i]);
-    }
-
-    // Returns the list of selected index values.
-    // in some contexts (template checkboxes) the value for an index is
-    // set to false to deselect instead of having it removed (via deselect()).
-    selected() {
-        return Object.keys(this.indexes).filter(
-            ind => {return Boolean(this.indexes[ind])})
-    }
-
-    isEmpty(): boolean {
-        return this.selected().length == 0;
-    }
-
-    clear() {
-        this.indexes = {};
-    }
-}
-
 export class EgGridDataSource {
 
     data: any[];
     sort: any[];
     allRowsRetrieved: boolean;
     getRows: (pager: Pager, sort: any[]) => Observable<any>;
-    indexedRows: {[index:string] : any};
 
     constructor() {
         this.sort = [];
@@ -590,7 +619,7 @@ export class EgGridDataSource {
     requestPage(pager: Pager): Promise<any> {
 
         if (
-            this.getPageOfRows(pager).length == pager.limit
+            this.getPageOfRows(pager).length === pager.limit
             // already have all data
             || this.allRowsRetrieved
             // have no way to get more data.
@@ -617,9 +646,9 @@ export class EgGridDataSource {
 
     // See if the last getRows() call resulted in the final set of data.
     checkAllRetrieved(pager: Pager, idx: number) {
-        if (this.allRowsRetrieved) return;
+        if (this.allRowsRetrieved) { return; }
 
-        if (idx == 0 || idx < (pager.limit + pager.offset)) {
+        if (idx === 0 || idx < (pager.limit + pager.offset)) {
             // last query returned nothing or less than one page.
             // confirm we have all of the preceding pages.
             if (!this.data.includes(undefined)) {