Skip to content

Commit

Permalink
v0.5.0
Browse files Browse the repository at this point in the history
* fix(query): `DOCUMENT_MODIFIED` action correctly updates data reducer when using nested collections in solution from @compojoom  - #88
* fix(query): fixed issue where `limit` was not included in query name - #90
* feat(query): `storeAs` support for subcollections
* feat(query): `where` now uses `=` in place of `::` within query string name (matches other query params)
  • Loading branch information
prescottprue authored May 4, 2018
2 parents e1051d4 + d2eb15b commit a2764a7
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 17 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ Storing data under a different path within redux is as easy as passing the `stor
},
```

**NOTE:** Not yet supported inside of subcollections (only at the top level)
**NOTE:** Usage of `"/"` and `"."` within `storeAs` can cause unexpected behavior when attempting to retrieve from redux state


#### Other Firebase Statics
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "redux-firestore",
"version": "0.4.3",
"version": "0.5.0",
"description": "Redux bindings for Firestore.",
"main": "lib/index.js",
"module": "es/index.js",
Expand Down
2 changes: 1 addition & 1 deletion src/actions/firestore.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ const changeTypeToEventType = {
function docChangeEvent(change, originalMeta = {}) {
return {
type: changeTypeToEventType[change.type] || actionTypes.DOCUMENT_MODIFIED,
meta: { ...originalMeta, doc: change.doc.id },
meta: { ...originalMeta, doc: change.doc.id, path: change.doc.ref.path },
payload: {
data: change.doc.data(),
ordered: { oldIndex: change.oldIndex, newIndex: change.newIndex },
Expand Down
11 changes: 8 additions & 3 deletions src/reducers/dataReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,21 @@ export default function dataReducer(state = {}, action) {
// Data to set to state is doc if doc name exists within meta
const data = docName ? get(payload.data, docName) : payload.data;
// Get previous data at path to check for existence
const previousData = get(state, pathFromMeta(meta));
const previousData = get(state, meta.storeAs || pathFromMeta(meta));
// Set data (without merging) if no previous data exists or if there are subcollections
if (!previousData || meta.subcollections) {
// Set data to state immutabily (lodash/fp's setWith creates copy)
return setWith(Object, pathFromMeta(meta), data, state);
return setWith(Object, meta.storeAs || pathFromMeta(meta), data, state);
}
// Otherwise merge with existing data
const mergedData = assign(previousData, data);
// Set data to state (with merge) immutabily (lodash/fp's setWith creates copy)
return setWith(Object, pathFromMeta(meta), mergedData, state);
return setWith(
Object,
meta.storeAs || pathFromMeta(meta),
mergedData,
state,
);
case DOCUMENT_MODIFIED:
case DOCUMENT_ADDED:
return setWith(
Expand Down
9 changes: 6 additions & 3 deletions src/reducers/orderedReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ function writeCollection(collectionState, action) {
return unionBy(collectionState, action.payload.ordered, 'id');
}

// Handle subcollections
if (meta.doc && meta.subcollections) {
// Handle subcollections (only when storeAs is not being used)
if (meta.doc && meta.subcollections && !meta.storeAs) {
if (!size(collectionState)) {
// Collection state does not already exist, create it with item containing
// subcollection
Expand All @@ -91,11 +91,14 @@ function writeCollection(collectionState, action) {
}),
);
}

if (meta.doc && size(collectionState)) {
return updateItemInArray(collectionState, meta.doc, item =>
// Update item in array (handling storeAs)
return updateItemInArray(collectionState, meta.storeAs || meta.doc, item =>
mergeObjects(item, action.payload.ordered[0]),
);
}

return action.payload.ordered;
}

Expand Down
10 changes: 7 additions & 3 deletions src/utils/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export function firestoreRef(firebase, dispatch, meta) {
*/
function whereToStr(where) {
return isString(where[0])
? `where::${where.join('')}`
? `where=${where.join(':')}`
: where.map(whereToStr);
}

Expand All @@ -160,7 +160,7 @@ export function getQueryName(meta) {
if (isString(meta)) {
return meta;
}
const { collection, doc, subcollections, where } = meta;
const { collection, doc, subcollections, where, limit } = meta;
if (!collection) {
throw new Error('Collection is required to build query name');
}
Expand All @@ -178,7 +178,11 @@ export function getQueryName(meta) {
if (!isArray(where)) {
throw new Error('where parameter must be an array.');
}
return basePath.concat(`?${whereToStr(where)}`);
basePath = basePath.concat(`?${whereToStr(where)}`);
}
if (typeof limit !== 'undefined') {
const limitStr = `limit=${limit}`;
basePath = basePath.concat(`${where ? '&' : '?'}${limitStr}`);
}
return basePath;
}
Expand Down
3 changes: 3 additions & 0 deletions src/utils/reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ export function pathFromMeta(meta) {
if (storeAs) {
return doc ? `${storeAs}.${doc}` : storeAs;
}
if (meta.path) {
return meta.path.split('/');
}
if (!collection) {
throw new Error('Collection is required to construct reducer path.');
}
Expand Down
28 changes: 24 additions & 4 deletions test/unit/actions/firestore.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,12 +227,20 @@ describe('firestoreActions', () => {
func({
docChanges: [
{
doc: { id: '123ABC', data: () => ({ some: 'value' }) },
doc: {
id: '123ABC',
data: () => ({ some: 'value' }),
ref: {
path: 'test/1/test2/test3',
},
},
type: 'modified',
},
],
size: 2,
doc: { id: '123ABC' },
doc: {
id: '123ABC',
},
});
func2(sinon.spy());
});
Expand Down Expand Up @@ -261,11 +269,23 @@ describe('firestoreActions', () => {
func({
docChanges: [
{
doc: { id: '123ABC', data: () => ({ some: 'value' }) },
doc: {
id: '123ABC',
data: () => ({ some: 'value' }),
ref: {
path: 'test/1/test2/test3',
},
},
type: 'modified',
},
{
doc: { id: '123ABC', data: () => ({ some: 'value' }) },
doc: {
id: '234ABC',
data: () => ({ some: 'value' }),
ref: {
path: 'test/1/test2/test3',
},
},
type: 'modified',
},
],
Expand Down
5 changes: 4 additions & 1 deletion test/unit/utils/query.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,17 @@ describe('query utils', () => {
it('is appended if valid', () => {
const where1 = 'some';
const where2 = 'other';
const whereOperator = '==';
meta = {
collection: 'test',
doc: 'doc',
where: [where1, '==', where2],
};
result = getQueryName(meta);
expect(result).to.equal(
`${meta.collection}/${meta.doc}?where::${where1}==${where2}`,
`${meta.collection}/${
meta.doc
}?where=${where1}:${whereOperator}:${where2}`,
);
});
});
Expand Down
4 changes: 4 additions & 0 deletions test/unit/utils/reducers.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ describe('reducer utils', () => {
pathFromMeta({ storeAs: 'testing' });
});

it('uses path as path if provided', () => {
expect(pathFromMeta({ path: 'testing' })).to.have.property(0, 'testing');
});

describe('updateItemInArray', () => {
it('is exported', () => {
expect(updateItemInArray).to.be.a('function');
Expand Down

0 comments on commit a2764a7

Please sign in to comment.