fetch data using react native sectionList - react-native

I'm working with firestore and i'm trying to fetch the data into my SectionList component. I want the sections to be broken up by the dates in my firestore data. For instance, if a user has booked a date of Sep 12th then the section header should show the previous Sunday (in this case Sep 9th)for the given date. My issue is I keep getting error "sectionlist length undefined". I understand it needs to be an array. How do I place the info from the array from firestore into the section 'data' and 'title' props.
I've already pulled data from the collection and placed it into this.state. I need to plug the info from dates into sections of my sectionlist component.
onCollectionUpdate = (querySnapshot) => {
var history = this.state.history;
let that = this;
querySnapshot.forEach((doc) => {
const { date, displayName, hours, image} = doc.data();
history.push({
key: doc.id,
date: doc.data().date,
displayName: doc.data().displayName,
hours: doc.data().hours,
image: doc.data().image,
});
});
that.setState({
history,
sections,
loading: false,
});
}
I was able to get the list to populate but each item is in its own view. I'm working on a way to get all dates within the same week to fall under the Sunday of that week view group. This is my function which i know i need to manipulate the way the array is pushed.
onCollectionUpdate = (querySnapshot) => {
// make copy of history object
let that = this;
let history = this.state.history;
let sectionExist = false;
//let history = JSON.stringify(JSON.parse(this.state.history);
querySnapshot.forEach((doc) => {
// find last sunday
var dates = moment(doc.data().date);
var weekOf = dates.startOf('week').valueOf();
var weekOfFormat = moment(weekOf).format('MMM Do')
console.log(doc);
history.push({
title: weekOfFormat,
data: [{
key: doc.id,
date: doc.data().date,
displayName: doc.data().displayName,
hours: doc.data().hours,
image: doc.data().image,
}]
});
});
that.setState({
history,
loading: false,
});
}

I think your misunderstanding is, that SectionList does not need an array of items. It needs an array of sections, where each section has an array of items (data).
Your code should look something like this:
onCollectionUpdate = (querySnapshot) => {
// make copy of history object
let history = JSON.stringify(JSON.parse(this.state.history);
querySnapshot.forEach((doc) => {
// find last sunday
let now = new Date(doc.data().date);
let today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
let lastSunday = new Date(today.setDate(today.getDate()-today.getDay()));
let lastSundayString = convertDateToMyStringFormat(lastSunday);
// check if section with this date as section title exists and push to that data if so
let sectionExists = false;
for(let i = 0; i < history.length; i++;) {
if(history[i].title === lastSundayString){
sectionExists = true;
history[i].data.push({
key: doc.id,
date: doc.data().date,
displayName: doc.data().displayName,
hours: doc.data().hours,
image: doc.data().image,
});
break;
}
}
// add new section if no such section found
if(!sectionExists){
history.push({
title: lastSundayString,
data: [{
key: doc.id,
date: doc.data().date,
displayName: doc.data().displayName,
hours: doc.data().hours,
image: doc.data().image,
}]
});
}
});
this.setState({
history,
loading: false,
});
}
You will have to implement your own convertDateToMyStringFormat function, to get a title string out of your Javascript Date object.

Related

Method to check if item is saved within the Nuxt Store

I currently have a Store that has the "Saved" items from a feed for a user. I'm trying to figure out the best/efficient way to check if the item is already saved within the store.
I can't think of any other way than grabbing the entire store's contents in each feed item and checking whether the id exists? Surely there's a better way?
FeedItem.vue
methods: {
savePost(Post) {
this.$store.commit('savedPosts/addItem', Post)
},
deletePost(Post) {
this.$store.commit('savedPosts/removeItem', Post)
}
}
Store
export const state = () => ({
items: [
],
})
export const mutations = {
updateItemsOnLoad(state, array) {
var oldItems = state.items
var newItems = array.flat()
var joinedItems = newItems.concat(oldItems);
state.items = joinedItems.flat()
},
addItem(state, item) {
state.items.push(item)
this.$warehouse.set('savedPosts', state.items)
},
removeItem(state, item) {
var index = state.items.findIndex(c => c.id == item.id);
state.items.splice(index, 1);
this.$warehouse.set('savedPosts', state.items)
},
}
So my main question: Is there a more efficient way to check whether a post exists within the items array without querying it on every feed item?

Update entire item in array - redux

I am trying to update a single object in an array of objects with a redux dispatch, I have tried answers to similar questions however I cannot seem to get it working. What I want to do, is when the action comes in, it should look for an item in the array with the same date as the action.options.date it should then replace that item in the array with the new item actions.options.data[0] which is the whole item object.
const initialState = {
isFetching: false,
monthArray: [],
searchOptions: {
currentMonth: moment().format('YYYY-MM'),
leeway: 1
},
availabilityOptions: {
Early: -1,
Late: -1,
Day: -1,
Twilight: -1,
Night: -1
}
};
case UPDATE_DAY_IN_MONTH_ARRAY:
return Object.assign({}, state, {
monthArray: state.monthArray.map(item => {
if (formatDate(item.date) === formatDate(action.options.date)) {
return action.options.data[0];
}
return item;
})
});
Action code: (Reason for data: data[0] is because an array of objects from mysql is returned)
export const updateDayInMonthArray = (date, data) => {
return {
type: UPDATE_DAY_IN_MONTH_ARRAY,
options: {
date,
data: data[0]
}
}
}
Dispatching the action
const updateDayInMonthArrayHandler = (date, data) => {
dispatch(updateDayInMonthArray(date, data));
}
Figured it out, and thank you guys for help. Wasn't React or Redux issue, was actually an issue with the node server returning data before checking what was updated.

Why can I add, but not remove an element from a set

I’m trying to update the notification count in my database.
I’m doing this by creating a set, which I add a UID to when I want to add to the notification count and removes a UID from the set when I want to subtract from the notification count.
I then take the size of the set and update the notification count.
the updateNotificationCount function is triggered by a lower order component.
However I can only get the database to update when isNewMatch is true. Why won’t it update the database when isNewMatch is false?
state = {notificationSet: new Set()}
updateNotificationCount = (uid, isNewMatch) => {
if (isNewMatch) {
this.setState(({ notificationSet }) => ({
notificationSet: new Set(notificationSet).add(uid)
}));
}
else {
this.setState(({ notificationSet }) => {
const newNotificationSet = new Set(notificationSet);
newNotificationSet.delete(uid);
return {
notificationSet: newNotificationSet
};
});
};
}
You don't need to do new Set() every time because you already initialize the state with new Set() so now you just do as follow:
state = {notificationSet: new Set()}
updateNotificationCount = (uid, isNewMatch) => {
let notificationSet;
if (isNewMatch) {
notificationSet=this.state.notificationSet;
notificationSet.add(uid);
this.setState({
notificationSet: notificationSet
});
} else {
notificationSet=this.state.notificationSet;
notificationSet.delete(uid);
this.setState({
notificationSet : notificationSet
});
};
}

How to compare results of two vuejs computed properties

Our application has events that users can apply to, as well as blog posts written about different events. We want to show users all of the blog posts for events where they have applied.
Each post has an eventId and each application object contains event.id. We want to show all of the posts where the the eventId is equal to one of the application.event.id's.
Here are our computed properties...
computed: {
...mapState(['posts', 'currentUser', 'applications']),
myApplications: function() {
return this.applications.filter((application) => {
return application.user.id === this.currentUser.uid
})
},
myEventPosts: function() {
return this.posts.filter((post => {
post.eventId.includes(this.myApplications.event.id)
})
}
How can we change meEventPosts to get the show the correct results?
Thanks!
This question is mostly related to JS, not Vue and calculated properties. It will be better if you create such a code snippet the next time, as I did below.
const posts = [{eventId: 1, name: 'Post 1'}, {eventId: 2, name: 'Post 2'}, {eventId: 3, name: 'Post 3'}];
const myApplications = [{eventId: 2, name: 'App 2'}];
const myEventPosts = function () {
const eventsIds = myApplications.map((app) => app.eventId);
return posts.filter((post) => eventsIds.includes(post.eventId));
}
console.log('posts:', myEventPosts());
So your myEventPosts computed property should look like:
myEventPosts: function() {
const eventsIds = this.myApplications.map((app) => app.eventId);
return this.posts.filter((post) => eventsIds.includes(post.eventId));
}

How to get a collection from firestore using data from another collection in react-Native.....What Am i Doing Wrong?

I have tried searching everywhere, from stackoverflow to GitHub but i can get a solution. I am trying to get list of users by using their userid that I get from a collection of businesses. What Am i doing wrong?
componentWillMount() {
//Loading all the business collections.
firebase.firestore().collection("business").onSnapshot((snapshot) => {
var bizs = [];
snapshot.forEach((bdt) => {
var userdt = [];
//get document id of a certain user in the business collections
firebase.firestore().collection('users').where("userid", "==", bdt.data().userid).get()
.then((snap) => {
snap.forEach(dc => {
//loading details of the user from a specific ID
firebase.firestore().collection("users").doc(dc.id).onSnapshot((udt) => {
userdt.push({
name: udt.data().fullname,
photourl: udt.data().photoURL,
location: bdt.data().location,
openhrs: bdt.data().openHrs,
likes: '20',
reviews: '3002',
call: bdt.data().contacts
});
console.log(userdt); //this one works
})
console.log(userdt); // but this one doesnt diplay anything just []
})
}).catch((dterr) => {
console.log(dterr)
})
});
this.setState({bizdata: bizs,loading: false
});
});
}
I am using react-native and firestore
Put log with some number,
like,
console.log('1',userdt);
console.log('2',userdt);
and check weather which one is appearing first, Maybe '2' is executing before updating the data