@ortoo/angular-resource
Version:
Magical CRUD resource management for angular
74 lines (62 loc) • 2.31 kB
text/typescript
import { Chain as ChainFunction } from './types';
import { ChainableQuery as IChainableQuery, Model, MultiQueryFunction, Query, QueryFunction, Resource } from './types';
interface ChainableQuery extends IChainableQuery<Model> {
$Model?: Resource<Model>;
}
// Chain a query into a new one (when the query updates so does the new query)
export const Chain: ChainFunction = chainConstructor;
function chainConstructor(origQry: ChainableQuery,
modelOrQryFn: (Resource<Model> | QueryFunction),
qryFn?: QueryFunction): Query<Model> {
let initialSync = false;
let ResToQry: Resource<Model>;
if (!qryFn) {
ResToQry = origQry.$Model;
qryFn = modelOrQryFn as QueryFunction;
} else {
ResToQry = modelOrQryFn as Resource<Model>;
}
// Make sure we have at least finished an initial load before generating the
// query object
const _qry = origQry.$promise.then(() => {
initialSync = true;
// We copy the array here so that we can do things like .map without auto-updating repercussions.
return qryFn.call(newqry, [...origQry]);
});
const newqry: Query<Model> = ResToQry.query(_qry);
// Watch our results. If they change then reattempt the query
origQry.$emitter.on('update', (newRes: any) => {
// Only do this if we have initially synced
if (initialSync) {
// We copy the array here so that we can do things like .map without auto-updating repercussions.
newqry.replace(qryFn.call(newqry, [...newRes]));
}
});
return newqry;
}
Chain.all = all;
function all(origQueries: Array<Query<Model>>, Model: Resource<Model>, qryFn: MultiQueryFunction) {
let newqry: Query<Model>;
const proms = [];
let initialSync: any;
let allqries: any[];
for (let ii = 0; ii < origQueries.length; ii++) {
const origQry = origQueries[ii];
proms.push(origQry.$promise);
origQry.$emitter.on('update', (newRes: any) => {
if (initialSync) {
allqries[ii] = [...newRes];
newqry.replace(qryFn.call(newqry, allqries));
}
});
}
newqry = Model.query(Promise.all(proms).then(res => {
initialSync = true;
allqries = [];
for (const result of res) {
allqries.push([...result]);
}
return qryFn.call(newqry, allqries);
}));
return newqry;
}