I think a better knowledge of javascript array methods will help me? - javascript

I'm trying to update an array of products in a custom mutation in keystone-next. I have got as far as the below, which works for the first product in my array. Obviously this only works if there is only 1 item in the array.
I know I need to map through the array in some way but I can't get my head round it.
const productIds = user.cart.map((cartItem) => cartItem.product.id);
console.log(productIds)
await context.lists.Product.updateMany({
// this is the bit that's wrong
data: [
{
id: productIds[0],
data: {
status: 'PENDING',
},
},
],
});

Yes, you need to map through your array of productIds
const productIds = user.cart.map((cartItem) => cartItem.product.id);
productIds.map(async (id) => {
await context.lists.Product.updateMany({
data: [
{
id,
data: {
status: 'PENDING',
},
},
],
});
})
But most efficiently you should handle the update in the first map without getting the array of productIds first. Like this
user.cart.map(async(cartItem) => {
await context.lists.Product.updateMany({
data: [
{
id: cartItem.product.id,
data: {
status: 'PENDING',
},
},
],
});
});

Something like this u mean?
const productIds = user.cart.map((cartItem) => cartItem.product.id);
console.log(productIds)
await context.lists.Product.updateMany({
data: productIds.map(productId => ({
id: productId,
data: {
status: 'PENDING',
},
}))
});

Related

Getting undefined result when trying to loop and filtering array

I am currently working with objects and arrays in nodejs in conjuction with filters. I am currenlty facing difficulty in figuring out how to properly traverse an object and filter for the desired results. Instead I am getting undefined. I have an object users and I am wanting to filter for each user configuration that has active === true and then ultimately display every users configuration with that filter in the final result. What is the right/best way to approach this? Should I use map?
Current Result:
undefined
Desired Result:
[
{
email: 'test1#email.com',
active: true
},
{
email: 'test3#email.com',
active: true
},
{
email: 'test4#email.com',
active: true
}
]
Code:
const users = [
{
name: 'User1',
configuration: [
{
email: 'test1#email.com',
active: true
},
{
email: 'test2#email.com',
active: false
}
],
},
{
name: 'User2',
configuration: [
{
email: 'test3#email.com',
active: true
},
{
email: 'test4#email.com',
active: true
}
],
},
];
const result = users.forEach(user => user.configuration.filter( x => {
let {
active
} = x;
return active === true;
}));
console.log(result);
you can use flatMap for this. forEach always returns undefined. usually if you want to return some array use map but since filter also returns an array you need to flat it to get your desired result hence flatMap
const users = [{name: 'User1',configuration: [ {email: 'test1#email.com',active: true},{email: 'test2#email.com',active: false}],},{name: 'User2',configuration: [ {email: 'test3#email.com',active: true},{email: 'test4#email.com',active: true}],},];
const result = users.flatMap(user => user.configuration.filter( x => x.active===true));
console.log(result);

Replace previous array of object is adding new element every time

I am new to the react js and Redux. Here , I have an array of object which is like ,
const initialState = {
Low: [
{
id: 0,
type: '',
count: '',
allowded: 6,
level: 'EASY'
}
],
Medium: [
{
id: 0,
type: '',
count: '',
allowded: 7,
level: 'MEDIUM'
}
],
High: [
{
id: 0,
type: '',
count: '',
allowded: 7,
level: 'TOUGH'
}
]
}
this is in the reducer .
Now,I do have an onChange function which actually changes the values in this array.
onChange(event, tobeupdated, id, type, noc, data) {
let newData = { ...this.props.data };
if (newData) {
let data = newData[type].map((object, index) => {
if (object.id === id) {
object[tobeupdated] = event.target.value;
const tobeData = newData[type];
this.props.updateLowLevel({tobeData, type}).then(() => {
let criteria_filled = this.disableAddbutton({ ...this.props.data }, type);
addedRow = `new${type}RowAdded`;
this.setState({
[addedRow]: criteria_filled ? true : false
})
});
}
From this, I am updating the value of that object. Depends upon the type .
Now, In action creator,
return (dispatch) => {
dispatch({
type: QUIZ_DATA,
data: tobeUpdated,
});
return Promise.resolve();
}
}
In my reducer, I am updating it like,
case QUIZ_DATA:
return {
...state,
[action.data.type]: [action.data.tobeData],
error: false,
}
Now, Here what is happening when I change the let's say type then it adds that array of object to that, but when I try to change the diff key that time what it does is,
In the array of object, one more obj gets added in the element. SO, because of that, I am not able to get that render properly.
Can anyone help me with this?

React - Loop through multiple nested arrays json object response then update State

I have some data that has the following shape. The schedule data also has other identifying information attached to it, being schedules.included which is an array of arrays. I want to loop through each included array and find it by type element. I'm not entirely sure how to get each included[] by type then update state with data from each array, respectively. Is forEach the correct approach?
const schedules = {
data: [
{
id: "2147483610",
type: "Schedule"
}
],
included: [
{
id: "21468486",
type: "Query",
name: "Query1"
},
{
id: "43573457345",
type: "DataSource",
name: "DataSource1"
}
]
};
I then want to update state with whatever data I need.
getData = () => {
axios({
method: "get",
url: `/endpoint/with/this/data`
})
.then(response => {
console.log(response);
var obj = schedules.included[i].type;
obj.forEach(function(type) {
alert(type.name);
});
this.setState({
schedules: schedules.data,
//update with name from type Query
});
})
.catch(error => console.log(error.response));
};
If you want to find the name of the element from the included array which has type = Query, and there is only one such element:
var query = schedules.included.find(el => el.type == "Query");
console.log(query.name); // output Query1
If there is more than one query element you could use filter to get all query elements, then loop thru them doing stuff with each one.
var queries = schedules.included.filter(el => el.type == "Query");
queries.forEach(q => console.log(q.name));
If there is only one element with the type you are looking for then you can use find or if there is more use filter.
const schedules = {
data: [
{
id: "2147483610",
type: "Schedule"
}
],
included: [
{
id: "21468486",
type: "Query",
name: "Query1"
},
{
id: "43573457345",
type: "DataSource",
name: "DataSource1"
}
]
};
const typeMatched = schedules.included.find( included => included.type === "Query");
console.log(': ', typeMatched);
const schedulesObj = {
data: [
{
id: "2147483610",
type: "Schedule"
}
],
included: [
{
id: "21468486",
type: "Query",
name: "Query1"
},
{
id: "43573457345",
type: "DataSource",
name: "DataSource1"
},
{
id: "21468482",
type: "Query",
name: "Query2"
},
{
id: "21468484",
type: "Query",
name: "Query3"
},
]
};
const typeMatchedArray = schedulesObj.included.filter( included => included.type === "Query");
console.log('Query Type List: ', typeMatchedArray)

How to return an array of objects in GraphQL, possibly using the same endpoint as the one that returns a single object?

I am making a GraphQL API where I would be able to retrieve a car object by its id or retrieve all the cars when no parameter is provided.
Using the code below, I am successfully able to retrieve a single car object by supplying id as a parameter.
However, in the case where I would expect an array of objects i.e. when I supply no parameter at all, I get no result on GraphiQL.
schema.js
let cars = [
{ name: "Honda", id: "1" },
{ name: "Toyota", id: "2" },
{ name: "BMW", id: "3" }
];
const CarType = new GraphQLObjectType({
name: "Car",
fields: () => ({
id: { type: GraphQLString },
name: { type: GraphQLString }
})
});
const RootQuery = new GraphQLObjectType({
name: "RootQueryType",
fields: {
cars: {
type: CarType,
args: {
id: { type: GraphQLString }
},
resolve(parent, args) {
if (args.id) {
console.log(cars.find(car => car.id == args.id));
return cars.find(car => car.id == args.id);
}
console.log(cars);
//***Problem Here***
return cars;
}
}
}
});
Test queries and their respective results:
Query 1
{
cars(id:"1"){
name
}
}
Query 1 Response (Success)
{
"data": {
"cars": {
"name": "Honda"
}
}
}
Query 2
{
cars{
name
}
}
Query 2 Response (Fail)
{
"data": {
"cars": {
"name": null
}
}
}
Any help would be much appreciated.
A Car and a List of Cars are effectively two separate types. A field cannot resolve to a single Car object one time, and an array of Car object another.
Your query is returning null for the name because you told it the cars field would resolve to a single object, but it resolved to an array instead. As a result, it's looking for a property called name on the array object and since one doesn't exist, it's returning null.
You can handle this in a couple of different ways. To keep things to one query, you can use filter instead of find and change the type of your query to a List.
cars: {
type: new GraphQLList(CarType), // note the change here
args: {
id: {
type: GraphQLString
},
},
resolve: (parent, args) => {
if (args.id) {
return cars.filter(car => car.id === args.id);
}
return cars;
}
}
Alternatively, you could split this into two separate queries:
cars: {
type: new GraphQLList(CarType),
resolve: (parent, args) => cars,
},
car: {
type: CarType,
args: {
id: {
// example of using GraphQLNonNull to make the id required
type: new GraphQLNonNull(GraphQLString)
},
},
resolve: (parent, args) => cars.find(car => car.id === args.id),
}
Check the docs for more examples and options.

How to get data from a complicated object / array structure?

I'm trying to get data from a complicated API structure. How would I get all the image from the following objects and arrays:
const x = { cars: [
{ types:
{
name: "VW",
image: [{ url: "http://www.lkjl.com" }]
}
},
{...},
{...}
]};
I know I can get the image url like this:
x.cars[0].types.image[0].url
But how can I print out all the image urls?
x.cars.map(item => {
return(
item.image[0].url; // this is wrong
);
});
Do I need to have another map inside the map function?
You could use Array#reduce with mapping the url property.
const
x = { cars: [{ types: { name: "VW", image: [{ url: "http://www.lkjl.com" },{ url: "http://www.alkjl.com" }] } }, { types: { name: "Tata", image: [{ url: "http://www.lskal.com" },{ url: "http://www.lkfjl.com" }] } }] },
images = x.cars.reduce((r, item) => r.concat(item.types.image.map(i => i.url)), []);
console.log(images);
Within the cars array you have image array inside the types object, So you have to iterate over both the arrays to print out all the images.
See the code below.
const x = { cars: [
{ types:
{
name: "VW",
image: [{ url: "http://www.lkjl.com" }]
}
},
{ types:
{
name: "VW",
image: [{ url: "http://www.lkjl12.com" }]
}
}
]};
x.cars.forEach(car => {
car.types.image.forEach( i => console.log(i.url));
})
i think you missed to access the 'types' object in your map function
it should be like this :
x.cars.map(item => {
return(
item.types.image[0].url; //this should work for you
);
});
x.cars.map(item => item.types.image[0].url)
I think you missed types:
x.cars.map(item => {
return(
item.types.image[0].url;
);
});
have you try this way ?
x.cars.map((item, key) => {
return(
item.types.image[0].url;
//you're missing 'types'
);
});
i hope it can help you.

Categories

Resources