How to find object in array by id number which is in another array in that object in vue - javascript

I have array of movie objects. I am passing id of movie genre to my state trying to extract object by movie genre ids. The problem is that every object in that array of movie objects have property named genre_ids which is an another array of multiple ids, and I am passing just one. I am having problem of mapping or find proper object that has that passed id in it's property genre_id which is array of multiple ids...can anyone help?
Here is the method in my state in which I am stuck
movieByGenre (state) {
return (genreId) => {
return state.popularMovies.find((movie) => {
movie.genreId.map((id) => {
return id === genreId
})
})
}
}
Here is data structure of movies

If I'm understanding your use case, something like this:
function movieByGenre(state) {
return genreId => {
const movies = state.popularMovies.filter(movie =>
movie.genre_ids.includes(genreId)
);
return movies[Math.floor(Math.random() * movies.length)];
};
}
This uses filter() to only return movies that the given genreId is in that movie's genre_ids collection. You can then use that filtered collection to return a single movie however you'd like.

after trying this solution I get error message in console "Error in render: "TypeError: Cannot read property 'title' of undefined""
NOTE: this is hardcoded genre id just for testing things out, which I know exist in movie collection
This is my component code from which I am calling state getter method
<template>
<p>{{movie.title}}</p>
</template>
<script>
export default {
genreId: "18",
computed: {
movie() {
return this.$store.getters.movieByGenre(this.genreId);
}
}
};
</script>

Related

React/Mobx mapping observable array to components

I'm stuck with trying to map an array to display components for each entry. Here's what I'm doing currently,
Here's my RankStore;
const RankStore = observable({
loading: false,
error: "",
rank: {} as RankInfo,
LoadRank() {
this.loading = true;
this.error = "";
GetRankInfo()
.then(action((json:any) => {
this.rank = json.rankDetails;
console.log(json)
this.loading = false;
}))
.catch(action((error: any) => {
this.error = error.message;
this.loading = false;
}));
}
});
export default RankStore;
In this observable RankStore I am loading the rank, which fetches from an API, and setting it to 'rank' which is an array of my model RankInfo, shown below;
interface RankInfo {
serviceNumber: string
capBadge: string
endDate: string
equivalentNatoRank: string
mainTrade: string
regtCorps: string
seniorityDate: string
actingPaidRank: string
startDate: string
substantiveRank: string
}
export default RankInfo;
Information received from the API looks like so;
Ordinary, to display this in a component, I would make the component an observer and simply call {RankStore.rank.serviceNumber} which works for my other Stores but not for this one as the data is a array containing two items. I am trying to MAP each array to a component so for each array it shows a component such as <h1> {RankStore.rank.serviceNumber} </h1> in this case it would render two components showing the respective service Numbers.
In the past I have done this as so;
{this.state.tickets.map((ticket) => (
<text key={ticket.id} value={ticket.id}>
{ticket.ticketApplication.firstName}{" "}
{ticket.ticketApplication.lastName}
</text>
))}
However, anytime I try to map {RankStore.rank} I always get 'MAP does not exist in 'rank''. What is the appropriate way to map arrays to components with MOBX?
It seems that you are setting the rank field as an object initially, and after the API call, changing it to an array. When rank is an object, it doesn't have the map function property on it.
So, instead of:
rank: {} as RankInfo
do this:
rank: [] as RankInfo[]
Initialize as an empty array of the RankInfo type.

Selecting specific object inside array of objects throwing undefined in Vuejs /Java app

In this app im building i have a little problem referring to adress the SPA to the selected item by its id.
Fetching my data to my end point(action) i got a array of objects , then through a getter i just grab all that data, and using the function find() i filter all the array throwing the object which contains the id referrig to the selected one.Lets say:
First- Exposing on the router the link and the condition of the id which demark the object to select
{
path: '/game/selected/:gameCrabId',
name: 'GameSelectedView',
props:true,
component: GameSelectedView,
},
Second- Eexposing the component where in i access through router link the supposed object which contains the requested id
<v-btn router-link :to="`/game/selected/${game.game_id}`" >Access</v-btn>
Third-Initializing the view in general of the supposed selected object
<template>
<v-container v-if="allGames">
<!-- <div>{{gameSelected}}</div> -->
</v-container>
</template>
<script>
import { mapActions, mapGetters, mapState } from "vuex";
export default {
name: "GameSelectedview",
props: ["gameCrabId"],
data() {
return {};
},
// props:{SelectedGameComponent:Object},
methods: {
...mapActions(["allGames"])
},
computed: {
...mapGetters(["getSelectedGame"]),
gameSelected() {
return this.getSelectedGame(this.gameCrabId);
}
},
async created() {
await this.allGames;
await this.gameSelected;
await console.log(this.gameSelected);
},
</script>
then on my state managment component (Vuex) , i trigger the method getter which eventually brings me once i click that button of step 2 , the object which has the same id than the required one, but first im exposing the state where in that array of objects is
state: {
allGamesData: {all_games:[
{"game_id": 1,"game_player": "Romi","game_score": 0},
{"game_id": 2,"game_player": "Messi","game_score": 0},
{"game_id": 3,"game_player": "CR7","game_score": 0},
]
},
},
getters:{
getSelectedGame: (state) => (gameCrabId) => {
console.log(gameCrabId);
return state.allGamesData.all_games.find((gameID) => {
gameID.game_id === gameCrabId;
});
},
}
And this is the getter which eventuallly accesses the state and that array of objects , and using a double arrow function first aims to the state ,and second through the parameter (gameCrabId)which is the once that expose the id so neccesary to complete the link to that selected item;then returning the access to that array of objects in my state , i just use the function find() to establish a comparison between that id carried by the parameter (gameCrabId) and the array of objects brought from the state , breaking the cycle once find the first comparable item in the objects which match with that id gameID.game_id === gameCrabId
In order to see if ,my id carrier works i set a log , and works , the number is brought , but for any reason the filter find() throws me undefined in the object selected despite of already have the id once the comparison get settled, being imposible retrieve any information of that object
Missing return from find()
The callback to Array.prototype.find() must return a Boolean, but currently it returns nothing, so the result of find() would always be null:
return state.allGamesData.all_games.find((gameID) => {
gameID.game_id === gameCrabId; // FIXME: No return statement
});
Mismatched types
game_id is a Number, but gameCrabId is a string, and getSelectedGame() uses === to compare the two, which requires the operands to have the same type. One solution is to perform explicit type conversion to ensure both operands are Number:
getters: {
getSelectedGame: state => gameCrabId => {
return state.allGamesData.all_games.find((gameID) => {
// return gameID.game_id === gameCrabId; // DON'T DO THIS
return gameID.game_id === Number(gameCrabId);
});
}
}
demo

Returning updated object after update to database instead of count

I am making an update to an entry in a database of food trucks. This is what my model looks like for this particulate update:
function editTruck(changes, id) {
return db('trucks')
.where({ id })
.update(changes)
.then(id => {
return findTruckById(id);
})
}
I want to return the actual updated entry in object form. As you can see above, I tried to accomplish this by drawing on another method in the model called findTruckById. This is what findTruckById looks like:
function findTruckById(id) {
return db('trucks')
.select('id', 'name', 'image', 'operator_id', 'cuisine_type', 'physical_address')
.where({ id })
.first()
}
This doesn't work because the response returned from the editTruck method is just a count of the entries in the database that were updated, which is 1, as opposed to an id or an array of ids for the entries. Therefore, it always just returns 1 and running 1 inside findTruckById returns an object equivalent to the entry in the trucks database with id 1, which is definitely not what we want. How can I solve this problem?
You already have the ID, you don't need the "update" to return it.
function editTruck(changes, id) {
return db('trucks')
.where({ id })
.update(changes)
.then(() => { // you already have the id, just use the `id` that is already in the scope
return findTruckById(id);
})
}

append to state array and add extra object key

sorry if the title isn't great but what I want to do is this:
componentDidMount() {
axios.get('http://thecatapi.com/api/images/get?format=xml&results_per_page=9')
.then((response) => {
parseString(response.data, (err, result) => {
result.response.data[0].images[0].image.map((cat) => this.setState({ cats: this.state.cats.concat(cat) }))
})
});
}
this function, pulls from catapi, then sets state of my cat state array to every cat object. each cat object has 3 keys from the cat api, how can I add an extra key called likes for every array object?
im thinking something like:
this.setState({ cats: this.state.cats.concat(cat), likes: 0 })
but obviously that doens't work
anyone got any ideas?
ah done it
just had to add it in like so:
result.response.data[0].images[0].image.map((cat) => (
cat.likes = 0,
this.setState({ cats: this.state.cats.concat(cat) }))
)
.map() returns an array which I believe means you are returning an array of items calling setState. Without seeing the overall logic I can't be sure exactly what you're doing but I would probably fetch the data, map it to a new array of objects, adding your key during the map, and lastly setState using the newly mapped array.

Firestore - Deep Queries

I have a Firestore that contains a collection (Items) that contains subcollections (called "things"). When I get my Items collection I get all of the child documents but none of the child collections. I would like to do a deep retrieval, one object called Items that contains the sub-collections.
I understand this is not possible out of the box, but I am struggling to write the code myself to do this.
Can anyone help?
constructor(public afs: AngularFirestore) {
//this.items = this.afs.collection('Items').valueChanges();
this.itemsCollection = this.afs.collection('Items', ref => ref.orderBy('year', 'asc'));
this.items = this.itemsCollection.snapshotChanges().map(changes => {
return changes.map(a => {
const data = a.payload.doc.data() as Item;
data.id = a.payload.doc.id;
return data;
});
});
}
getItems() {
return this.items;
}
Yes, you can execute the code below to get what you want to. Basically this code gets for each item its things subcollection:
getItems(): Promise<any> {
return this.db.collection('items').get().then(
items => {
return this.getThingsForItems(items);
});
}
getThingsForItems(items): Promise<any> {
return Promise.all(items.docs.map(async (element) => {
var things = []
const response = await this.db.collection('items')
.doc(element.id).collection('things').get();
response.forEach(subcollectionItem => {
things.push(subcollectionItem.data());
});
return { Item: element.data(), Things: things }
}));
}
The getItems method will return a promisse that contains your items with its things subcollection.
Something like that:
Keep in mind that this query can become a slow-running query since it is making a get for each document of the items collection.
So you might should consider denormalize your database or transform the things subcolletion in an array of the items documents (in this case you should be aware that a document has a max size of 1MB, so do not consider this option if you are array can become too big).

Categories

Resources