Skip to content

feat(utils): new utilities to simplify common queries #206

Open
@nt4f04uNd

Description

What is the feature?
Populates syntax sugar

What version would this apply to?
I wrote my examples on 2.2.6.

Do you have thoughts/examples on how the feature would be used (i.e. API)?
I have a bunch of ready functions I wrote on Typescript. I want you to include them into your library, or something like these ones, because current query structure is very annoying.

Here's a straightforward example, how I use them

import { IAppState } from 'src/store/rootReducer'
import { createFirestoreQueries, createPopulates, populateWithDocId, IMapStoreToProps } from 'myModule'
import { compose } from 'redux';

interface IProps extends
   IMapStateToProps,
   IMapDispatchToProps,
   IMapStateToProps2 { }

interface IMapStateToProps {
   uid: string
}
interface IOwnProps { }
const mapStateToProps = (state: IAppState, ownProps: IOwnProps): IMapStateToProps => ({
   uid: state.firebase.auth.uid
});

interface IMapStateToProps2 {
   privateCollection: object
}
interface IOwnProps2 {
   uid: string
}

// just convinient to have an object, when you have a lot of populates in one firestoreConnect
const populates = {
   privateCollection: createPopulates(
      populateWithDocId('incomingRequests', 'users', 'profile')
   )
}
const mapStoreToProps = (ownProps: IOwnProps2): IMapStoreToProps[] => createFirestoreQueries({
   path: `users/${ownProps.uid}/private/friends/incomingRequests`, populates: populates.privateCollection
})
const mapStateToProps2 = (state: IAppState, ownProps: IOwnProps2): IMapStateToProps2 => ({
   privateCollection: populate(state.firestore, `users/${ownProps.uid}/private/friends/incomingRequests`, populates.privateCollection)
});

export default compose(
   connect(mapStateToProps, null) as any, // as any because something goes wrong in types and I'm getting strange error
   firestoreConnect(mapStoreToProps),
   connect(mapStateToProps2),
)(class Requests extends React.Component<IProps, IState> {

Description

Since I discovered that third argument in populate() from your lib can be a function, I started to write my sugar

createPopulates()

A higher order function. Basiclly is just accepts as many populates objects or populate functions and returns an array of them

Example:

const populates = createPopulates(
    populateWithDocId('incomingRequests', 'users', 'profile')
)

This is same as if you had written like this:

const populates = (...args: any) => [
    populateWithDocId('incomingRequests', 'users', 'profile')(args)
]

populateWithDocId()()

This function proceeds doc id to to the result of query as custom field

parameters:

  1. childCollection — name of collection which contains document
  2. rootCollection — name of collection which contains values to populate
  3. fieldName — alias name to stored field

Second invocation passes dataKey and originalData

createFirestoreQueries()

Creates an array of queries, accepts infinitely many objects of structure { path: <pathString>, populates: <resultOfCreatePopulates>}

Example:

const mapStoreToProps = (ownProps: IOwnProps2): IMapStoreToProps[] => createFirestoreQueries({
   path: `users/${ownProps.uid}/private/friends/incomingRequests`, populates: populates.privateCollection
})

This can be written as:

const mapStoreToProps = (ownProps: IOwnProps2): IMapStoreToProps[] => [{
collection: 'users', doc: ownProps.uid, subcollections: [{
      collection: 'private', doc: 'friends', subcollections: [{
         collection: 'incomingRequests'
      }]
   }],
   populates: populates.privateCollection
}]

pathOptions() ???

Alias of JSON.stringify()
For using in createFirestoreQueries()'s path

Basiclly you can add additional query params to path on every level.
I wrote this function, but now I doubt in her need.

parameters:

  1. options — object with additional query params, such as where or startAt

Example:

createFirestoreQueries({
   path: `users/${ownProps.uid}/private(${pathOptions({
      where: ['nicknameId', '==', 'example']
   })})/friends/incomingRequests`
})

It's replacement for

[{
   collection: 'users', doc: ownProps.uid, subcollections: [{
      collection: 'private', doc: 'friends', where: ['nicknameId', '==', 'example'], subcollections: [{
         collection: 'incomingRequests'
      }]
   }],
   populates: populates.privateCollection
}]

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions