Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(populate): support populates with references #365

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 26 additions & 9 deletions src/utils/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ function arrayToStr(key, value) {
}

/**
* Pcik query params from object
* Pick query params from object
* @param {object} obj - Object from which to pick query params
* @returns {object} Object of query params by name
*/
Expand All @@ -218,6 +218,21 @@ function pickQueryParams(obj) {
].reduce((acc, key) => (obj[key] ? { ...acc, [key]: obj[key] } : acc), {});
}

/**
* Parse id from string or reference
* @param {string|firebase.firestore.DocumentReference} value - id or reference
* @returns {string} Parsed id
*/
function parseId(value) {
let id;
if (typeof value === 'string' || value instanceof String) {
id = value
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason why we can't just return here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it could just return

} else if (value && value.id) {
id = value.id;
}
return id;
}

/**
* Join/serilize query params
* @param {object} queryParams - Query settings
Expand Down Expand Up @@ -558,7 +573,7 @@ export function populateList(firebase, originalObj, p, results) {
return Promise.all(
map(originalObj, (id, childKey) => {
// handle list of keys
const populateKey = id === true || p.populateByKey ? childKey : id;
const populateKey = parseId(id === true || p.populateByKey ? childKey : id);
return getPopulateChild(firebase, p, populateKey).then(pc => {
if (pc) {
// write child to result object under root name if it is found
Expand Down Expand Up @@ -631,21 +646,21 @@ export function promisesForPopulate(
// Data is a single object, resolve populates directly
populatesForData.forEach(p => {
const childDataVal = get(originalData, p.child);
if (typeof childDataVal === 'string' || childDataVal instanceof String) {
const id = parseId(childDataVal);
if (id) {
return promisesArray.push(
getPopulateChild(firebase, p, childDataVal).then(v => {
getPopulateChild(firebase, p, id).then(v => {
// write child to result object under root name if it is found
if (v) {
set(
results,
`${p.storeAs ? p.storeAs : p.root}.${childDataVal}`,
`${p.storeAs ? p.storeAs : p.root}.${id}`,
v,
);
}
}),
);
}

// Single Parameter is list
return promisesArray.push(
populateList(firebase, childDataVal, p, results),
Expand All @@ -671,16 +686,18 @@ export function promisesForPopulate(
return;
}

const id = parseId(idOrList);

// Parameter of each list item is single ID
if (typeof idOrList === 'string' || idOrList instanceof String) {
if (id) {
return promisesArray.push(
// eslint-disable-line
getPopulateChild(firebase, p, idOrList).then(v => {
getPopulateChild(firebase, p, id).then(v => {
// write child to result object under root name if it is found
if (v) {
set(
results,
`${p.storeAs ? p.storeAs : p.root}.${idOrList}`,
`${p.storeAs ? p.storeAs : p.root}.${id}`,
v,
);
}
Expand Down