Цель состоит в том, чтобы фильтровать массив объектов другим массивом объектов.Каждый массив поступает из разных источников.
Следующая настройка может показаться странной, хотя по нескольким здесь не упомянутым причинам, к сожалению, необходимо.
- Шаг первый - получить из базы данных Firebaseмассив объектов с метаданными о некоторых (самых последних) загруженных сообщениях (allposts).
- На втором шаге этот массив будет отфильтрован для идентификаторов пользователей и текстов (filterArrayIds).
- На третьем шаге для каждого отфильтрованного идентификатора пользователя будет вызван API для получения подробной информации обо всех существующих публикациях соответствующего идентификатора пользователя.Они будут объединены в один массив сообщений (fetchJSONFiles).
- На четвертом шаге этот объединенный массив сообщений должен быть отфильтрован по всем текстам в массиве текстов шага два (filterJSON).
Ниже мое решение до сих пор.К сожалению, я не могу сделать так, чтобы функции выполнялись последовательно, так что особенно fetchJSONfiles () полностью завершен до вызова filterJSON ().
Я застрял здесь на несколько часов ... любая помощь очень важнаоценил бы и сделал мой день.Спасибо!
Пример данных:
allposts: [
{
dateofpost: "1539181118111",
textid: "1",
userid: "Alice",
},
{
dateofpost: "1539181118222",
textid: "3",
userid: "Bob",
},
]
-
allfilteredTexts: [
{
title: "Lorem",
textid: "1",
},
{
title: "Ipsum",
textid: "2",
},
{
title: "Dolor",
textid: "3",
},
]
Ожидаемый результат:
latestPosts: [
{
title: "Lorem",
textid: "1",
},
{
title: "Dolor",
textid: "3",
},
]
Мое решение на данный момент:
class Explore extends React.Component {
constructor(props) {
super(props);
this.state = {
allposts: [],
textids: [],
userids: [],
allfilteredTexts: [],
};
}
componentDidMount() {
const allfilteredTexts = {...this.state.allfilteredTexts}
firebase
.firestore()
.collection("allposts")
.orderBy("dateofpost")
.get()
.then(snapshot => {
const allposts = this.state.allposts;
snapshot.forEach(doc => {
allposts.push({
userid: doc.data().userid,
textid: doc.data().textid,
dateofpost: doc.data().dateofpost,
});
});
this.setState({
allposts: allposts,
});
})
.catch(function(error) {
console.log("Error getting documents: ", error);
})
.then(() => {
this.filterArrayIds();
})
.then(() => {
this.fetchJSONFiles();
})
.finally(() => {
this.filterJSON();
});
}
filterArrayIds() {
var userids = this.state.userids
var textids = this.state.textids
if (this.state.allposts) {
var filtereduserids = [...new Set([].concat(...this.state.allposts.map(o => o.userid)))];
var filteredtextids = [...new Set([].concat(...this.state.allposts.map(p => p.textid)))];
this.setState({
userids: filtereduserids,
textids: filteredtextids,
})
}
}
fetchJSONFiles() {
if (this.state.userids) {
this.state.userids.forEach((username) => {
var filteredTexts = []
const options = {username} //here would be more API options //
getFile(options)
.then((file) => {
filteredTexts = JSON.parse(file || '[]');
})
.then (() => {
Array.prototype.push.apply(filteredTexts, this.state.allfilteredTexts);
this.setState({
allfilteredTexts: filteredTexts,
})
})
}
}
filterJSON(){
let latestPosts = (this.state.allfilteredTexts.filter(
(el) => { return el.id.indexOf(this.state.textids) !== -1;
}));
}
render () {
return (
<div>
<Switch>
<Route
path='/explore/latest/'
render={(props) => <ExploreLatest {...props} allposts={this.state.allposts} allfilteredTexts={this.state.allfilteredTexts} />}
/>
</Switch>
</div>
)
}
}
export default Explore;