How do you divide the number of objects imported from axios? - dictionary

As for importing data, Axios will bring in 100 pieces, and is there any way to put only 20 pieces out of 100 pieces separately in then or useState?
I'd like to know if there's any other way.
I would like to know if there is any other way other than using rowum >=20 as a query statement.
const [list, setList] = useState([]);
useEffect(() => {
axios.get('http://localhost:8080/movielist/getMovieList_boxoffice')
.then(res => {setList(res.data)})
.catch(err => console.log(err))
},[already_released]);
{
list.map ((item, index) => {
return (
<ol>
<li>objectnum = {index+1}</li>
</ol>
)
})
}
`
const [list, setList] = useState([0,20]);
useEffect(() => {
axios.get('http://localhost:8080/movielist/getMovieList_boxoffice')
.then(res => {setList(res.data)})
.catch(err => console.log(err))
},[already_released]);
{
list.map ((item, index(21)) => {
var arr = index
var arr1 = index(0,21)
return (
<div>
<ol>
<li>objectnum = {arr1+1}</li>
</ol>
</div>
)
})
}
`

You can use splice to keep only the first 20 items of your data: res.data.splice(20))
In your case:
useEffect(() => {
axios.get('http://localhost:8080/movielist/getMovieList_boxoffice')
.then(res => {setList(res.data.splice(20))})
.catch(err => console.log(err))
},[already_released]);

Related

Getting parent and child document data from Firestore in a single Vue component

I have a parent (organisation) document in firestore and multiple child documents. I want load he data based on if the parent or child was clicked in the same component.
The below code works, the data is shown, but updates to the child organisations are not shown in real time (I have to reload to see it.). I'm guessing it is because I'm binding the array orgArray and not the object org that I actually use to display the data. Is there a way to just bind the object and not the whole array?
<template>
<div class="route-container">
<div class="item__container">
<FmisTitle/>
<Hero
:orgName="org.name"
:orgLogo="org.logo"
:orgState="org.state"
:orgNumber="org.number"
:orgType="org.type"
:orgDateStart="org.dateStart"
:orgDateEnd="org.dateEnd"
:orgDateStartF="org.dateStartFunctional"
:orgDateEndF="org.dateEndFunctional"
:orgCoverImage="org.coverImagex745"
:childRef="org.id"
:orgRef="orgRef"
/>
<Contact
:orgEmail="org.email"
:orgPhone="org.phoneNumber"
:orgAddress="org.address"
:orgWebsite="org.website"
:orgSocials="org.socials"
:childRef="org.id"
:orgRef="orgRef"
/>
<ButtonDuo/>
</div>
</div>
</template>
export default {
data() {
return {
org: {},
orgArray: [],
orgRef: '',
};
},
created() {
firebase.auth().onAuthStateChanged((user) => {
firestore.collectionGroup('people').where('userId', '==', user.uid).get().then((query) => {
query.forEach((userRef) => {
const orgRef = userRef.ref.parent.parent.id;
this.orgRef = orgRef;
if (!this.$route.params.parent) {
const organisation = firestore.collection('organisations').doc(orgRef).collection('childOrganisations').where('name', '==', this.$route.params.id);
this.$bind('orgArray', organisation).then((doc) => {
const org = doc[0];
this.org = org;
});
} else {
const organisation = firestore.collection('organisations').doc(orgRef);
this.$bind('org', organisation);
}
});
});
}, (error) => {
console.log(error);
});
},
}
I solved this by using the id from the childOrg and getting the data with that id, that way I could bind the data object directly.
firebase.auth().onAuthStateChanged((user) => {
firestore.collectionGroup('people').where('userId', '==', user.uid).get().then((query) => {
query.forEach((userRef) => {
const orgRef = userRef.ref.parent.parent.id;
this.orgRef = orgRef;
if (this.$route.query.parent !== 'true') {
firestore.collection('organisations').doc(orgRef).collection('childOrganisations').where('name', '==', this.$route.params.id)
.get()
.then((q) => {
q.forEach((ref) => {
const orgId = ref.id;
const organisation = firestore.collection('organisations').doc(orgRef).collection('childOrganisations').doc(orgId);
this.$bind('org', organisation);
});
});
} else {
const organisation = firestore.collection('organisations').doc(orgRef);
this.$bind('org', organisation);
}
});
});
}, (error) => {
console.log(error);
});

Add Firebase image URL to my collection

I have the following method I'm accessing when my VueJS component is loading:
getServices () {
fb.servicesCollection.get().then(querySnapshot => {
this.serviceList = []
querySnapshot.forEach(doc => {
const { name, icon } = doc.data()
fb.storage.ref().child(icon).getDownloadURL().then(function (url) {
console.log(url)
})
this.serviceList.push({id: doc.id, name: name, icon: 'iconURL'})
})
this.isLoading = false
}).catch(error => {
console.log(error)
})
}
What I want to achieve is to get the url to replace the current 'iconURL' string. Didn't find any method to do that in the last couple of hours. Please help!
The following should do the trick. (However note that I could no test it, so it may need a bit of fine tuning... You can report how it works in the comments and we correct it if necessary)
Since you want to execute several getDownloadURL() asynchronous calls to Firebase Storage in parallel, you have to use Promise.all(), since getDownloadURL() returns a promise, see the doc.
getServices () {
let namesArray = []
let docIdArray = []
fb.servicesCollection.get().then(querySnapshot => {
this.serviceList = []
let promises = []
querySnapshot.forEach(doc => {
const icon = doc.data().icon;
promises.push(fb.storage.ref().child(icon).getDownloadURL())
namesArray.push(doc.data().name)
docIdArray.push(doc.id)
})
return Promise.all(promises)
})
.then(results => {
results.forEach((value, index) => {
this.serviceList.push({id: docIdArray[index], name: namesArray[index], icon: value})
})
})
}).catch(error => {
console.log(error)
})
}
This is how I got it in the end...
getServices () {
fb.servicesCollection.get().then(querySnapshot => {
this.serviceList = []
querySnapshot.forEach(doc => {
const { name, icon } = doc.data()
fb.storage.ref(icon).getDownloadURL().then(url => {
this.serviceList.push({id: doc.id, name: name, icon: url})
})
})
this.isLoading = false
}).catch(error => {
console.log(error)
})
}
Thank you for all your efforts to help me!!! Highly appreciate it!

TypeError: Cannot set property 'words' of undefined

I have this action in my vuex store:
loadExercises ({commit}) {
commit('setLoading', true)
const db = firebase.firestore()
db.collection('exercises').get()
.then(querySnapshot => {
const exercises = []
querySnapshot.forEach((doc) => {
exercises.push({
title: doc.data().title,
language: doc.data().language,
translated: doc.data().translated,
lastOpen: doc.data().lastOpen,
dueDate: doc.data().dueDate,
uid: doc.data().uid,
userId: doc.data().userId,
words: [{ word: '', uid: '', translation: '' }]
})
db.collection('exercises').doc(doc.data().uid).collection('words').get()
.then(words => {
const wordsArray = []
words.forEach(word => {
wordsArray.push(word.data())
})
let exercise = this.getters.loadedExercise(doc.data().uid)
exercise.words = wordsArray
})
.catch(error => {
commit('setLoading', false)
console.log(error)
})
})
commit('setLoading', false)
commit('setLoadedExercises', exercises)
})
.catch(error => {
commit('setLoading', false)
console.log(error)
})
}
It is supposed to fetch exercises from a firebase cloudstore db. It works on some routes but not all.
When using these two getters it works:
loadedExercises (state) {
return state.loadedExercises
},
loadedExercise (state) {
return (exerciseId) => {
return state.loadedExercises.find(exercise => {
return exercise.uid === exerciseId
})
}
}
But when I use these getters:
upcomingExercises (state, getters) {
return getters.loadedExercises.filter(exercise => {
return exercise.dueDate > 0
})
},
latestExercises (state, getters) {
return getters.loadedExercises.splice(0, 5)
},
it does not work I just get "TypeError: Cannot set property 'words' of undefined". What is it that I do wrong?
It looks to me like you aren't returning the values back to the function.
Try replacing
db.collection('exercises').get()
with
return db.collection('exercises').get()
and
db.collection('exercises').doc(doc.data().uid).collection('words').get()
with
return db.collection('exercises').doc(doc.data().uid).collection('words').get()

Conditionally fetching data in epic

Say I have the following epic:
const getPostsEpic = (action$, store) => {
return action$.ofType(actionTypes.REQUEST_POSTS)
.switchMap(action =>
ajax.getJSON(`api/posts?key=${action.key}`)
.map(response =>
receivePosts({type: RECEIVE_POSTS, posts: response})
).takeUntil(
action$.ofType(actionTypes.ABORT_GET_POSTS)
)
};
and say my reducer is something like
function reducer(
state = {
isFetching: false,
didInvalidate: true,
items: []
},
action
) {
switch (action.type) {
case INVALIDATE_POSTS:
return Object.assign({}, state, {
didInvalidate: true
})
case REQUEST_POSTS:
return Object.assign({}, state, {
isFetching: true,
didInvalidate: false
})
case RECEIVE_POSTS:
return Object.assign({}, state, {
isFetching: false,
didInvalidate: false,
items: action.posts,
})
default:
return state
}
}
I want to make sure that posts are only fetched if my state's didInvalidate === true, is there a good way to make this work with my epic? Could do something like this, but it's not that pretty IMO:
const getPostsEpic = (action$, store) => {
return action$.ofType(actionTypes.REQUEST_POSTS)
.switchMap(action => {
const state = store.getState();
if (state.didInvalidate) {
return ajax.getJSON(`api/posts?key=${action.key}`)
.map(response =>
receivePosts({type: RECEIVE_POSTS, posts: response})
).takeUntil(
action$.ofType(actionTypes.ABORT_GET_POSTS)
)
else {
return Observable.of({type: RECEIVE_POSTS, posts: state.items});
}
}
};
Btw, I'm using this with React. I'm sure this is a pretty common problem, so maybe there's a better way of handling this outside my epics?
You can use if for branching, like this:
const mockAjax = () => Promise.resolve({posts: [4, 5, 6, 7]});
const fetchPost = (action$) => Rx.Observable.fromPromise(mockAjax())
.map(({posts}) => ({type: RECEIVE_POSTS, posts}))
.takeUntil(action$.ofType(ABORT_GET_POSTS))
const defaultPosts = (action$, store) => Rx.Observable.of({type: RECEIVE_POSTS, posts: store.getState().items});
const getPostsEpic = (action$, store) =>
action$.ofType(USER_REQUEST)
.mergeMap(() => Rx.Observable.if(
() => store.getState().didInvalidate, // condition
fetchPost(action$), // if true
defaultPosts(action$, store) // if false
)
.do(x => console.log(x))
)
Check the demo in her: http://jsbin.com/jodaqopozo/edit?js,console,output
Clicking valid/invalid button and then click 'Post Request' will log different value.
Hope this helps.

React Native / Firebase - upload image with additional info

I used this block of code to select an image when button is pressed to upload to firebase.
<TouchableHighlight onPress={ () => this._pickImage() }
style={styles.button}>
<Text
style={styles.buttonText}>
Select a Photo
</Text>
</TouchableHighlight>
_pickImage() {
this.setState({ uploadURL: '' })
ImagePicker.launchImageLibrary({}, response => {
uploadImage(response.uri)
.then(url => this.setState({ uploadURL: url }))
.catch(error => console.log(error))
});
}// end _pickImage
const uploadImage = (uri, mime = 'application/octet-stream') => {
return new Promise((resolve, reject) => {
const uploadUri = Platform.OS === 'ios' ? uri.replace('file://', '') : uri
const sessionId = new Date().getTime()
let uploadBlob = null
const imageRef = storage.ref('images').child(`${sessionId}`)
fs.readFile(uploadUri, 'base64')
.then((data) => {
return Blob.build(data, { type: `${mime};BASE64` })
})
.then((blob) => {
uploadBlob = blob
return imageRef.put(blob, { contentType: mime })
})
.then(() => {
uploadBlob.close()
return imageRef.getDownloadURL()
})
.then((url) => {
resolve(url)
})
.catch((error) => {
reject(error)
})
})
}
This works fine. How can I change this to let the user select photo and then hit another button store additional info for the image like Description entered by the user into the same data structure in firebase?

Resources