Skip to content

Commit

Permalink
Multiple values arrayUnion arrayRemove 🌬 [merge]
Browse files Browse the repository at this point in the history
Fixes for #183 #177 ⭐️
  • Loading branch information
mesqueeb authored Mar 22, 2019
2 parents a9e3dd5 + ac7b35d commit 0fb47dd
Show file tree
Hide file tree
Showing 9 changed files with 271 additions and 76 deletions.
52 changes: 37 additions & 15 deletions dist/index.cjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,43 +103,65 @@ function setBaseFirebase(firebaseDependency) {
_BaseFirebase = firebaseDependency;
}
var ArrayUnion = /** @class */ (function () {
function ArrayUnion(payload) {
function ArrayUnion() {
var payload = [];
for (var _i = 0; _i < arguments.length; _i++) {
payload[_i] = arguments[_i];
}
this.isArrayHelper = true;
this.payload = payload;
}
ArrayUnion.prototype.executeOn = function (array) {
if (!array.includes(this.payload)) {
array.push(this.payload);
}
this.payload.forEach(function (item) {
if (!array.includes(item)) {
array.push(item);
}
});
return array;
};
ArrayUnion.prototype.getFirestoreFieldValue = function () {
return _BaseFirebase.firestore.FieldValue.arrayUnion(this.payload);
var _a;
return (_a = _BaseFirebase.firestore.FieldValue).arrayUnion.apply(_a, this.payload);
};
return ArrayUnion;
}());
var ArrayRemove = /** @class */ (function () {
function ArrayRemove(payload) {
function ArrayRemove() {
var payload = [];
for (var _i = 0; _i < arguments.length; _i++) {
payload[_i] = arguments[_i];
}
this.isArrayHelper = true;
this.payload = payload;
}
ArrayRemove.prototype.executeOn = function (array) {
var index = array.indexOf(this.payload);
if (index > -1) {
array.splice(index, 1);
}
this.payload.forEach(function (item) {
var index = array.indexOf(item);
if (index > -1) {
array.splice(index, 1);
}
});
return array;
};
ArrayRemove.prototype.getFirestoreFieldValue = function () {
return _BaseFirebase.firestore.FieldValue.arrayRemove(this.payload);
var _a;
return (_a = _BaseFirebase.firestore.FieldValue).arrayRemove.apply(_a, this.payload);
};
return ArrayRemove;
}());
function arrayUnion(payload) {
return new ArrayUnion(payload);
function arrayUnion() {
var payload = [];
for (var _i = 0; _i < arguments.length; _i++) {
payload[_i] = arguments[_i];
}
return new (ArrayUnion.bind.apply(ArrayUnion, [void 0].concat(payload)))();
}
function arrayRemove(payload) {
return new ArrayRemove(payload);
function arrayRemove() {
var payload = [];
for (var _i = 0; _i < arguments.length; _i++) {
payload[_i] = arguments[_i];
}
return new (ArrayRemove.bind.apply(ArrayRemove, [void 0].concat(payload)))();
}
function isArrayHelper(value) {
// this is bugged in vuex actions, I DONT KNOW WHY
Expand Down
52 changes: 37 additions & 15 deletions dist/index.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,43 +97,65 @@ function setBaseFirebase(firebaseDependency) {
_BaseFirebase = firebaseDependency;
}
var ArrayUnion = /** @class */ (function () {
function ArrayUnion(payload) {
function ArrayUnion() {
var payload = [];
for (var _i = 0; _i < arguments.length; _i++) {
payload[_i] = arguments[_i];
}
this.isArrayHelper = true;
this.payload = payload;
}
ArrayUnion.prototype.executeOn = function (array) {
if (!array.includes(this.payload)) {
array.push(this.payload);
}
this.payload.forEach(function (item) {
if (!array.includes(item)) {
array.push(item);
}
});
return array;
};
ArrayUnion.prototype.getFirestoreFieldValue = function () {
return _BaseFirebase.firestore.FieldValue.arrayUnion(this.payload);
var _a;
return (_a = _BaseFirebase.firestore.FieldValue).arrayUnion.apply(_a, this.payload);
};
return ArrayUnion;
}());
var ArrayRemove = /** @class */ (function () {
function ArrayRemove(payload) {
function ArrayRemove() {
var payload = [];
for (var _i = 0; _i < arguments.length; _i++) {
payload[_i] = arguments[_i];
}
this.isArrayHelper = true;
this.payload = payload;
}
ArrayRemove.prototype.executeOn = function (array) {
var index = array.indexOf(this.payload);
if (index > -1) {
array.splice(index, 1);
}
this.payload.forEach(function (item) {
var index = array.indexOf(item);
if (index > -1) {
array.splice(index, 1);
}
});
return array;
};
ArrayRemove.prototype.getFirestoreFieldValue = function () {
return _BaseFirebase.firestore.FieldValue.arrayRemove(this.payload);
var _a;
return (_a = _BaseFirebase.firestore.FieldValue).arrayRemove.apply(_a, this.payload);
};
return ArrayRemove;
}());
function arrayUnion(payload) {
return new ArrayUnion(payload);
function arrayUnion() {
var payload = [];
for (var _i = 0; _i < arguments.length; _i++) {
payload[_i] = arguments[_i];
}
return new (ArrayUnion.bind.apply(ArrayUnion, [void 0].concat(payload)))();
}
function arrayRemove(payload) {
return new ArrayRemove(payload);
function arrayRemove() {
var payload = [];
for (var _i = 0; _i < arguments.length; _i++) {
payload[_i] = arguments[_i];
}
return new (ArrayRemove.bind.apply(ArrayRemove, [void 0].concat(payload)))();
}
function isArrayHelper(value) {
// this is bugged in vuex actions, I DONT KNOW WHY
Expand Down
111 changes: 91 additions & 20 deletions docs/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,45 +10,116 @@ Firebase is a peer dependency; It will use your existing version.

## Setup

It's super easy to set up and start using! Below is a short example how to setup your vuex easy firestore module:
Vuex Easy Firestore is all about adding just a few lines to each Vuex module to automatically have it sync with your Firestore. We'll take you through the next three steps:

1. Add 4 lines of code to your vuex-module
2. Import the vuex-module wrapped in vuex-easy-firestore plugin
3. dispatch `openDBChannel` action
1. Create a Firebase init file
2. Create a Vuex store init file
3. Create and export your vuex-easy-firestore modules

### 1. Create a Firebase init file

First we'll create a function that enables Firebase and Firestore and will attempt to enable offline persistence. You can read more on this in the [Firebase documentation](https://firebase.google.com/docs/firestore/manage-data/enable-offline).

```js
// ~config/firebase.js
import * as Firebase from 'firebase/app'
import 'firebase/firestore'

function initFirebase () {
Firebase.initializeApp({ /* your Firebase config */})
return new Promise((resolve, reject) => {
Firebase.firestore().enablePersistence()
.then(resolve)
.catch(err => {
if (err.code === 'failed-precondition') {
reject(err)
// Multiple tabs open, persistence can only be
// enabled in one tab at a a time.
} else if (err.code === 'unimplemented') {
reject(err)
// The current browser does not support all of
// the features required to enable persistence
}
})
})
}

export { Firebase, initFirebase }
```

### 2. Create a Vuex store init file

```js
// ~store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import VuexEasyFirestore from 'vuex-easy-firestore'
Vue.use(Vuex)

// import from step 1
import { Firebase, initFirebase } from '~config/firebase.js'
// import from step 3 (below)
import myModule from './modules/myModule.js'

// do the magic 🧙🏻‍♂️
const easyFirestore = VuexEasyFirestore(
[myModule],
{logging: true, FirebaseDependency: Firebase}
)

// include as PLUGIN in your vuex store:
const storeData = {
// ... your store
plugins: [easyFirestore]
}
const store = new Vuex.Store(storeData)

// initFirebase
initFirebase()
.catch(error => {
// take user to a page stating an error occurred
// (might be a connection error, or the app is open in another tab)
})

export default store
```

It's very important that we take the user to an error page when something went wrong with the Firestore initialisation.

When something went wrong and there was no data retrieved from cache or from the server, the user might still be able to see your app but without any data. **In this case it's important that we prevent the user from being able to use the app and start writing data**, because this could potentially overwrite data on the server.

Finally, passing `{logging: true}` as second param for `VuexEasyFirestore` will enable console.logging on each api call. This is recommended for debugging initially, but should be disabled on production.

### 3. Create and export your vuex-easy-firestore modules

```js
import createEasyFirestore from 'vuex-easy-firestore'
// ~store/modules/myModule.js

const myModule = {
firestorePath: 'myDocs',
firestoreRefType: 'collection', // or 'doc'
moduleName: 'myModule',
statePropName: 'data',
namespaced: true, // automatically added
// you can also add your own state/getters/mutations/actions
}

// do the magic 🧙🏻‍♂️
const easyFirestore = createEasyFirestore(myModule, {logging: true})

// include as PLUGIN in your vuex store:
const store = {
// ... your store
plugins: [easyFirestore]
// this object is your store module (will be added as '/myModule')
// you can also add state/getters/mutations/actions
state: {},
getters: {},
mutations: {},
actions: {},
}

// open the DB channel
store.dispatch('myModule/openDBChannel')
export default myModule
```

By dispatching `openDBChannel` the library will automatically retrieve all docs from your Firestore collection called `myDocs` and save them in your state at `myModule.data`.
## In a nutshell

You can edit and add docs and all changes will be synced to Firestore! Please check "[add and manage data](add-and-manage-data.html)" for basic information how to use the actions that are prepared for you.
Basically what Vuex Easy Firestore does is register your vuex-easy-firestore module to the store and give you a bunch of easy to use actions to retrieve and insert/modify/delete Firestore data.

### Dev logging
For **retrieving data**, eg. just by doing `dispatch('myModule/openDBChannel')` the library will automatically retrieve all docs from your Firestore collection called `myDocs` and save them in your state at `myModule.data`.

Passing `{logging: true}` as second param will enable console.logging on each api call. This is recommended for debugging initially, but should be disabled on production.
For **editing data**, you can use `dispatch('myModule/set', {someProp: newVal})` or `dispatch('myModule/insert', {name: 'a new record'})` and all changes will be synced to Firestore!

## First steps

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": "vuex-easy-firestore",
"version": "1.30.1",
"version": "1.31.0",
"description": "Easy coupling of firestore and a vuex module. 2-way sync with 0 boilerplate!",
"main": "dist/index.cjs.js",
"module": "dist/index.esm.js",
Expand Down
36 changes: 20 additions & 16 deletions src/utils/arrayHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isAnyObject, isPlainObject } from 'is-what'
import { isAnyObject, isPlainObject, isArray } from 'is-what'
import * as Firebase from 'firebase/app'
import 'firebase/firestore'

Expand All @@ -11,46 +11,50 @@ export function setBaseFirebase (firebaseDependency) {
export class ArrayUnion {
isArrayHelper: boolean
payload: any
constructor (payload: any) {
constructor (...payload: any) {
this.isArrayHelper = true
this.payload = payload
}
executeOn (array: any[]) {
if (!array.includes(this.payload)) {
array.push(this.payload)
}
this.payload.forEach(item => {
if (!array.includes(item)) {
array.push(item)
}
})
return array
}
getFirestoreFieldValue () {
return _BaseFirebase.firestore.FieldValue.arrayUnion(this.payload)
return _BaseFirebase.firestore.FieldValue.arrayUnion(...this.payload)
}
}

export class ArrayRemove {
isArrayHelper: boolean
payload: any
constructor (payload: any) {
constructor (...payload: any) {
this.isArrayHelper = true
this.payload = payload
}
executeOn (array: any[]) {
const index = array.indexOf(this.payload)
if (index > -1) {
array.splice(index, 1)
}
this.payload.forEach(item => {
const index = array.indexOf(item)
if (index > -1) {
array.splice(index, 1)
}
})
return array
}
getFirestoreFieldValue () {
return _BaseFirebase.firestore.FieldValue.arrayRemove(this.payload)
return _BaseFirebase.firestore.FieldValue.arrayRemove(...this.payload)
}
}

export function arrayUnion (payload) {
return new ArrayUnion(payload)
export function arrayUnion (...payload) {
return new ArrayUnion(...payload)
}

export function arrayRemove (payload) {
return new ArrayRemove(payload)
export function arrayRemove (...payload) {
return new ArrayRemove(...payload)
}

export function isArrayHelper (value) {
Expand Down
Loading

0 comments on commit 0fb47dd

Please sign in to comment.