Created
September 10, 2018 20:56
-
-
Save jwheat/54c1a8c8132961755d2b9bc9185c01ad to your computer and use it in GitHub Desktop.
React Native PouchDB replication problem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from "react"; | |
import { StyleSheet, Text, View, TouchableHighlight } from "react-native"; | |
import Header from "../components/Header.js"; | |
import HomeContent from "../components/HomeContent.js"; | |
import Tabs from "../components/Tabs.js"; | |
import config from "../client/config.js"; | |
import SessionsList from "../screens/SessionsList"; | |
import PouchDB from "pouchdb-react-native"; | |
PouchDB.plugin(require("pouchdb-find")); | |
PouchDB.plugin(require("pouchdb-load")); | |
PouchDB.plugin(require("pouchdb-adapter-asyncstorage").default); | |
PouchDB.debug.enable("pouchdb:find"); | |
export default class Home extends Component { | |
static navigationOptions = { | |
title: config.client.homeText | |
}; | |
constructor(props) { | |
super(props); | |
this.state = { | |
localDB: [], | |
statearray: [] | |
}; | |
var db = new PouchDB("localDB", { | |
adapter: "asyncstorage", | |
auto_compaction: true | |
}); | |
/* Check to see if we've loaded the dump file */ | |
db.get("_local/initial_load_complete") | |
.catch( | |
function(err) { | |
if (err.status !== 404) { | |
throw err; | |
} | |
db.load(config.client.dumpFileURL) | |
.then(function() { | |
return db.put({ _id: "_local/initial_load_complete" }); | |
}) | |
.then(function(res) { | |
db.createIndex({ | |
index: { | |
fields: ["type", "start_date", "start_time", "title"] | |
} | |
}); | |
}) | |
.then( | |
function() { | |
console.log("index created"); | |
this.buildStateArray(); | |
}.bind(this) | |
) | |
.catch(function(err) { | |
console.log(err); | |
}); | |
}.bind(this) | |
) | |
.then(function(res) { | |
db.createIndex({ | |
index: { | |
fields: ["type", "start_date", "start_time", "title"] | |
} | |
}).then(function(res) { | |
console.log("index created"); | |
db.find({ | |
selector: { type: { $eq: "sessions" } } | |
}).then(function(result) { | |
console.log("DEBUG: --- Dump docs from find"); | |
console.log(result.docs); | |
}); | |
}); | |
}) | |
.then( | |
function() { | |
this.buildStateArray(); | |
}.bind(this) | |
) | |
.catch(function(err) { | |
console.log(err); | |
}); | |
this.localDB = db; | |
this.remoteDB = new PouchDB(config.client.database); | |
} | |
buildStateArray = () => { | |
/* TODO: Make this a loop */ | |
console.log("DEBUG: ================================"); | |
console.log("DEBUG: BUILD STATE ARRAY"); | |
this.setDocs(config.days[0][1], 1); | |
this.setDocs(config.days[1][1], 2); | |
this.setDocs(config.days[2][1], 3); | |
this.setDocs(config.days[3][1], 4); | |
console.log("DEBUG: STATE ARRAY BUILT"); | |
console.log("DEBUG: ================================"); | |
}; | |
dumpDB = () => { | |
return this.localDB.allDocs({ include_docs: true }).then(function(res) { | |
console.log(res); | |
}); | |
}; | |
goReplicate = () => { | |
console.log("DEBUG: goReplicate"); | |
this.localDB.replicate | |
.from(this.remoteDB, { | |
filter: function(doc) { | |
return doc.type === "sessions"; | |
} | |
}) | |
.on( | |
"complete", | |
function() { | |
console.log("DEBUG: sync completed"); | |
this.refreshData(); | |
}.bind(this) | |
) | |
.on("error", function(err) { | |
console.log("sync ERROR!"); | |
}); | |
}; | |
setDocs = (which_day, state_variable) => { | |
console.log("DEBUG: ::> setDocs " + which_day + "-----"); | |
/* TODO: remove this block after it is working */ | |
// just for debug to verify all docs are in the database | |
this.localDB.allDocs({ include_docs: true }).then(function(res) { | |
console.log(res); | |
}); | |
this.localDB | |
.find({ | |
selector: { | |
$and: [ | |
{ type: { $exists: true } }, | |
{ type: { $eq: "sessions" } }, | |
{ start_time: { $gt: true } }, | |
{ start_date: { $exists: true } }, | |
{ start_date: { $eq: which_day } } | |
] | |
} | |
}) | |
.then( | |
function(result) { | |
console.log("DEBUG: Day " + state_variable + " sessions"); | |
let obj = Object.assign({}, this.state.statearray); | |
if (state_variable === 1) { | |
obj.dayonedocs = result.docs; | |
} | |
if (state_variable === 2) { | |
obj.daytwodocs = result.docs; | |
} | |
if (state_variable === 3) { | |
obj.daythreedocs = result.docs; | |
} | |
if (state_variable === 4) { | |
obj.dayfourdocs = result.docs; | |
} | |
this.setState({ | |
statearray: obj | |
}); | |
}.bind(this) | |
) | |
.catch(function(error) { | |
console.log("Day " + state_variable + " - error"); | |
console.error(error); | |
}); | |
}; | |
refreshData() { | |
this.localDB | |
.changes({ | |
live: true, | |
include_docs: true | |
}) | |
.on("change", this.handleChange.bind(this)) | |
.on("complete", console.log.bind(console, "[Change:Complete]")) | |
.on("error", console.log.bind(console, "[Change:Error]")); | |
} | |
handleChange(change) { | |
console.log("DEBUG: [Change:Change]", change); | |
var doc = change.doc; | |
if (!doc) { | |
return; | |
} | |
//if (doc._deleted) { | |
// this.removeDoc(doc); | |
//} else { | |
this.addOrUpdateDocChanges(doc); | |
//} | |
} | |
addOrUpdateDocChanges(newDoc) { | |
/* TODO: Deal with this mess for the four days */ | |
let dayOne = [...this.state.statearray["dayonedocs"]]; | |
//let dayTwo = [...this.state.statearray["daytwodocs"]]; | |
//let dayThree = [...this.state.statearray["daythreedocs"]]; | |
//let dayFour = [...this.state.statearray["dayfourdocs"]]; | |
console.log("DEBUG: addOrUpdateDocChanges"); | |
var docs = dayOne; | |
/* TODO: build a function for this so it can be called for each day */ | |
let index = docs.findIndex(el => el._id === newDoc._id); | |
console.log(docs); | |
if (index !== -1) { | |
console.log("DEBUG: Found it"); | |
docs[index] = { | |
...docs[index], | |
title: newDoc.title, | |
start_date: newDoc.start_date, | |
start_time: newDoc.start_time, | |
end_date: newDoc.end_date, | |
end_time: newDoc.end_time, | |
instructors: newDoc.instructors, | |
track: newDoc.track, | |
room: newDoc.room, | |
floor: newDoc.floor, | |
level: newDoc.level, | |
session_canceled: newDoc.session_canceled | |
}; | |
let obj = Object.assign({}, this.state.statearray); | |
obj.dayonedocs = docs; | |
this.setState({ | |
statearray: obj | |
}); | |
console.log("DEBUG: after update state"); | |
console.log(this.state.statearray["dayonedocs"]); | |
} else { | |
// this item does not exist, contactinate to end of the list | |
this.setState({ | |
docs: this.state.statearray["dayonedocs"].concat(newDoc) | |
}); | |
// re-sort the list allowing the new document to pop into the proper place | |
this.sortState(); | |
} | |
} | |
sortState() { | |
const sortedState = [] | |
.concat(this.state.statearray["dayonedocs"]) | |
.sort((a, b) => a.start_date > b.start_date) | |
.sort((a, b) => a.start_time > b.start_time); | |
//.sort((a, b) => a.title > b.title); | |
let obj = Object.assign({}, this.state.statearray); | |
obj.dayonedocs = sortedState; | |
this.setState({ | |
statearray: obj | |
}); | |
} | |
render() { | |
return ( | |
<View style={styles.container}> | |
<Header displayLogo={true} style={styles.appHeader} /> | |
<HomeContent text={config.client.clientEventName} textStyle="heading" /> | |
<View> | |
<TouchableHighlight | |
onPress={() => { | |
this.goReplicate(); | |
}} | |
style={styles.evaluateModalButton} | |
> | |
<Text style={styles.evaluateModalText}>RELOAD</Text> | |
</TouchableHighlight> | |
<TouchableHighlight | |
onPress={() => { | |
this.dumpDB(); | |
}} | |
style={styles.evaluateModalButton} | |
> | |
<Text style={styles.evaluateModalText}>DUMP</Text> | |
</TouchableHighlight> | |
</View> | |
<View style={styles.tabContainer}> | |
<Tabs> | |
{/* First tab */} | |
<View | |
title={config.days[0][0]} | |
style={styles.content} | |
navigation={this.props.navigation} | |
> | |
<SessionsList | |
start_date={config.days[0][1]} | |
docs={this.state.statearray.dayonedocs} | |
/> | |
</View> | |
{/* Second tab */} | |
<View | |
title={config.days[1][0]} | |
style={styles.content} | |
navigation={this.props.navigation} | |
> | |
<SessionsList | |
start_date={config.days[1][1]} | |
docs={this.state.statearray.daytwodocs} | |
/> | |
</View> | |
{/* Third tab */} | |
<View | |
title={config.days[2][0]} | |
style={styles.content} | |
navigation={this.props.navigation} | |
> | |
<SessionsList | |
start_date={config.days[2][1]} | |
docs={this.state.statearray.daythreedocs} | |
/> | |
</View> | |
{/* Fourth tab */} | |
<View | |
title={config.days[3][0]} | |
style={styles.content} | |
navigation={this.props.navigation} | |
> | |
<SessionsList | |
start_date={config.days[3][1]} | |
docs={this.state.statearray.dayfourdocs} | |
/> | |
</View> | |
</Tabs> | |
</View> | |
</View> | |
); | |
} | |
} | |
const styles = StyleSheet.create({ | |
// App container | |
container: { | |
flex: 1 | |
}, | |
appHeader: { | |
//flex: 1, | |
height: 50 | |
}, | |
tabContainer: { | |
flex: 6, // Take up all screen | |
backgroundColor: config.colors.darkPrimary // Background color | |
}, | |
// Tab content container | |
content: { | |
flex: 1, // Take up all available space | |
justifyContent: "center", // Center vertically | |
alignItems: "center", // Center horizontally | |
backgroundColor: config.colors.white // Darker background for content area | |
}, | |
// Content header | |
header: { | |
margin: 10, | |
color: config.colors.primaryText, | |
fontFamily: "Avenir", | |
fontSize: 26 | |
}, | |
// Content text | |
text: { | |
marginHorizontal: 20, // Add horizontal margin | |
color: config.colors.primaryText, // Semi-transparent text | |
textAlign: "center", // Center | |
fontFamily: "Avenir", | |
fontSize: 18 | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment