I am trying to reach out to the "testdata":"two" property values [like 'EH']. While I was taking that property, I am facing "Cannot read property" this issue, How I fix this issue in Cypress?
[{
"testdata": "one",
"TC": {
"EHQ0": "Address",
}
},
{
"testdata": "two",
"TC": {
"EH": "Student",
"E1": "Question For Name",
"EnglishText_E1": "Question For Name"
}
}
]
You have an array of objects, so either index or find.
const data = [{
"testdata": "one",
"TC": {
"EHQ0": "Address",
}
},
{
"testdata": "two",
"TC": {
"EH": "Student",
"E1": "Question For Name",
"EnglishText_E1": "Question For Name"
}
}
]
const objTwo = data.find(obj => obj.testdata === 'two')
const ehProp = objTwo.TC.EH
Related
I am not sure how I should set cart.items to a new array, I have already made a copy of the original cache because I learned Apollo does not let you directly edit the cache, but I am still getting the following error
Error: Cannot assign to read only property 'items' of object '#'
Do I need to make a copy of the items array? And if so how do I go about changing the array on the current objects item field?
Here are my console.logs
You can ignore the typename fields as they are irrelevant to the problem
addItem
{
"__typename": "Cart",
"items": [
{
"__typename": "CartItem",
"name": "Item 3"
},
{
"__typename": "CartItem",
"name": "Item 4"
},
{
"__typename": "CartItem",
"name": "New Item!"
}
]
}
carts
{
"carts": [
{
"__typename": "Cart",
"id": "1",
"items": [
{
"__typename": "CartItem",
"id": "1",
"name": "Item 1"
},
{
"__typename": "CartItem",
"id": "2",
"name": "Item 2"
}
]
},
{
"__typename": "Cart",
"id": "2",
"items": [
{
"__typename": "CartItem",
"id": "3",
"name": "Item 3"
},
{
"__typename": "CartItem",
"id": "4",
"name": "Item 4"
}
]
}
]
}
So it seems you need to remake the items array as well since items is its own gql object type the easiest way to do this was to do it all at once with a map.
Please note the comment as that was an important detail I learned
// IMPORTANT NOTE when updating the cache of a query you must return the
// same fields as the original query even if you aren't using them in the code
const GET_CARTS = gql`
query {
carts{
id
items{
id
name
}}} `;
const MUTATION = gql`
mutation AddItem($input:MutationAddItemInput!) {
addItem(input: $input){
items{
id
name
}
}
}
`;
const { loading, error, data } = useQuery(GET_CARTS)
const [addItem] = useMutation(MUTATION, {
// refetchQueries: [{ query: GET_CARTS }]
update(cache, { data: { addItem } }) {
// addItem is the response of the query of add item function
console.log({ addItem });
// #ts-ignore
let { carts } = cache.readQuery({ query: GET_CARTS });
console.log({ carts })
// make a new array out of the carts array and add the new item to the array if the id of the cart is 2
let newCarts = carts.map((cart: Cart) => {
if (cart.id === "2") {
return { ...cart, items: [...addItem.items] }
} else {
return cart
}
})
console.log({ newCarts });
cache.writeQuery({
query: GET_CARTS,
data: { carts: newCarts }
// data: { carts: [{ id: "1", items: [{ id: "2", name: "an item" }] }] }
})
}
})
And lastly you will call the addItem function from the use mutation hook
I cannot mutate a list of objects completely, because only the last element of the array will be mutated.
What already works perfectly is, if I put each element ({play_positions_id: ...}) in the array manually like here:
mutation CreateProfile {
__typename
create_profiles_item(data: {status: "draft", play_positions: [{play_positions_id: {id: "1"}}, {play_positions_id: {id: "2"}}]}) {
id
status
play_positions {
play_positions_id {
abbreviation
name
}
}
}
}
Output:
{
"data": {
"__typename": "Mutation",
"create_profiles_item": {
"id": "1337",
"status": "draft",
"play_positions": [
{
"play_positions_id": {
"id": "1",
"abbreviation": "RWB",
"name": "Right Wingback"
}
},
{
"play_positions_id": {
"id": "2",
"abbreviation": "CAM",
"name": "Central Attacking Midfielder"
}
}
],
}
}
}
Since you can add many of those elements, I defined a variable/argument like here
mutation CreateProfile2($cpppi: [create_profiles_play_positions_input]) {
__typename
create_profiles_item(data: {status: "draft", play_positions: $cpppi}) {
id
status
play_positions {
play_positions_id {
id
abbreviation
name
}
}
}
}
Variable object for above:
"cpppi": {
"play_positions_id": {
"id": "1"
},
"play_positions_id": {
"id": "2
}
}
Output:
{
"data": {
"__typename": "Mutation",
"create_profiles_item": {
"id": "1338",
"play_positions": [
{
"play_positions_id": {
"id": "2",
"abbreviation": "CAM",
"name": "Central Attacking Midfielder"
}
}
],
}
}
}
Schema:
input create_profiles_input {
id: ID
status: String!
play_positions: [create_profiles_play_positions_input]
}
input create_profiles_play_positions_input {
id: ID
play_positions_id: create_play_positions_input
}
input create_play_positions_input {
id: ID
abbreviation: String
name: String
}
At the last both snippets, only the last object with the id "2" will be mutated. I need these to use the defined input type from my backend.
I figured it out. I got it wrong with the brackets in the variable. Here the solution:
"cpppi": [
{
"play_positions_id": {
"id": "1"
}
},
{
"play_positions_id": {
"id": "2"
}
}
]
This is my query to add a new field or increment a nested attribute
const params = {
TableName: process.env.DYNAMODB_GAMES_TABLE,
Key: {
id: gameId
},
UpdateExpression: 'set players.#player.#score = players.#player.#score + :s',
ExpressionAttributeNames: {
'#player': playerId,
'#score': 'score'
},
ExpressionAttributeValues: {
':s': 1
},
ReturnValues: "ALL_NEW"
};
This is the error I get
{
"message": "The document path provided in the update expression is invalid for update",
"code": "ValidationException",
"time": "2020-05-21T03:03:14.328Z",
"requestId": "Q04QEP1G3E2LAM43I04ADLM4IRVV4KQNSO5AEMVJF66Q9ASUAAJG",
"statusCode": 400,
"retryable": false,
"retryDelay": 27.814212380235393
}
My object looks like
{
"id": "09e7a690",
"players": {
"M3EDJeHtoAMCLJg": [
{
"cardId": "1",
"cardTitle": "test",
"pun": "this is a pun"
}
]
}
}
I have some problem in mongoose project.
I try to populate and use getter but not all data
But now all virtuals appear in document.
I'm using mongoose.Schema and mongoose.Model
Here is example of my test code
const GroupsSchema = schema({
title: String,
users: [{
type: schema.Types.ObjectId,
ref: 'Users'
}]
});
const UsersSchema = schema({
name: String,
avatar: String
}, {
toJSON: {
virtuals: true
}
});
class Users extends Model {
get name() {
return {
name: this.name
};
}
get avatar() {
return {
avatar: this.avatar
};
}
}
Populating document
const groups = await Groups.find({}).populate('users').exec();
My current result:
[
{
"_id": "5c9bb51626924f0a08aa8c3d",
"title": "GroupName"
"users": [
{
"_id": "5c8e37169fc1f9000f8c333b",
"name": "Jack",
"avatar": "avatar.jpg",
"name": {
"name": "Jack",
},
"avatar": {
"avatar": "avatar.jpg"
}
}
]
}
]
How can I populate document with content of only name getter?
Desired result:
[
{
"_id": "5c9bb51626924f0a08aa8c3d",
"title": "GroupName"
"users": [
{
"name": "Jack"
}
]
}
]
I have an API that gives out data like this with the attributes in a fields property.
{
records: [
{
id: "123",
fields: {
author: {
id: "1",
name: "Paul"
},
title: "My awesome blog post",
comments: [
{
id: "324",
commenter: {
id: "2",
name: "Nicole"
}
}
]
}
}
]
};
When normalizing, I now handle this with a simple processStrategy: (input, parent, key) => input.fields but I would like denormalise this again so that the denormalised entities to contain this fields structure because the API expects it this way.
So far denormalising my normalised data with const denormalizedData = denormalize([123], [article], normalizedData.entities) omits the field:
[
{
"author": {
"id": "1",
"name": "Paul"
},
"title": "My awesome blog post",
"comments": [
{
"id": "324",
"commenter": {
"id": "2",
"name": "Nicole"
}
}
]
}
]
I cannot find anything in the api docs on how to add extra processing on denormalisation, any idea?
Because processStrategy is intended for pre-processing of data during the normalization process, it is not going to be executed during the denormalization. For your use case, I would not use this feature and simply structure your schemas as follows:
const { schema, denormalize, normalize } = normalizr;
const user = new schema.Entity("users");
const comment = new schema.Entity("comments", { commenter: user });
const commentList = [comment];
const post = new schema.Entity("posts", {
fields: { author: user, comments: commentList }
});
const postList = [post];
const mockApiResponse = {
records: [
{
id: "123",
fields: {
author: {
id: "1",
name: "Paul"
},
title: "My awesome blog post",
comments: [
{
id: "324",
commenter: {
id: "2",
name: "Nicole"
}
}
]
}
}
]
};
const normalizedResponse = normalize(mockApiResponse.records, postList);
const denormalizedResponse = denormalize(
normalizedResponse.result,
postList,
normalizedResponse.entities
);
console.log("normalizedResponse", normalizedResponse);
console.log("denormalizedResponse", denormalizedResponse);
This will give you the result you are looking for. If for some reason, you need to stick to your current implementation, I would recommend implementing a transform on your request prior to sending it back to the server. As an example, axios solves this with their transformRequest feature.