I cannot find a way to set serializableCheck to false only for specific slice.
const store = configureStore({
reducer: {
ApiSignalMenu: ApiSignalMenuSlice.reducer,
ApiSignalData: ApiSignalDataSlice.reducer,
ApiHistoricalMenu: ApiHistoricalMenuSlice.reducer,
ApiHistoricalYearData: ApiHistoricalYearDataSlice.reducer,
ApiUpProbabilityMenu: ApiUpProbabilityMenuSlice.reducer,
ApiUpProbabilityData: ApiUpProbabilityDataSlice.reducer,
ApiMoverData: ApiMoverDataSlice.reducer,
ApiChartingMenu: ApiChartingMenuSlice.reducer,
ApiChartingData: ApiChartingDataSlice.reducer,
ApiTicker: ApiTickerSlice.reducer
},
// middleware: (getDefaultMiddleware) =>
// getDefaultMiddleware({
// serializableCheck: false
// }
middleware: (getDefaultMiddleware) => getDefaultMiddleware({
serializableCheck: {
ignoredPaths: ['ApiMoverData.apiData.0'],
}
})
});
I have array data in : ApiMoverData
If I set : ignoredPaths: ['ApiMoverData.apiData.0'],
Then I got error again for A non-serializable value was detected in an action, in the path: payload.0. Value:, ApiMoverData
And
Then I got error again for Then I got error again for A non-serializable value was detected in the state, in the path: ApiMoverData.apiData.0
ApiMoverData.apiData.1, Then ApiMoverData.apiData.2, again.
How to set serializableCheck to false to all my array data in specific slice ?
This post : Is there a way to set the serializableCheck to false for one reducer only in redux?
did not tell a specific answer.
Thank You
EDIT :
My structure data looks like this :
Array [
ApiMoverData {
"change": "1,43",
"company": "Garuda Maintenance Facility Aero Asia Tbk.",
"id": 0,
"last": "71",
"ticker": "GMFI",
"value": "99.343.200",
"volume": "13.992",
},
ApiMoverData {
"change": "1,44",
"company": "Kimia Farma Tbk.",
"id": 1,
"last": "1.765",
"ticker": "KAEF",
"value": "956.208.000",
"volume": "5.433",
}
]
If I set : ignoredPaths: ['ApiMoverData.apiData']
Then I got error again for A non-serializable value was detected in an action, in the path: payload.0. Value:, ApiMoverData
And
Then I got error again for A non-serializable value was detected in the state, in the path: ApiMoverData.apiData.0
ApiMoverData.apiData.1, Then ApiMoverData.apiData.2, again.
Same Error
recomended by #phry do not use class instance in redux-toolkit. Because it will effect negative in future. Also we will not be able to use Redux-Persist. Just use non-class javascript object and store that.
Related
I'm using React Native with Expo, Jest for snapshot testing and Redux Toolkit with query. I want to create a snapshot but always getting an error TypeError. I think problem is in my mocks, I don't know how to mock an entire object of data. Example below:
jest.mock('../../services', () => ({
useGetOfficeDataQuery: jest.fn().mockReturnValue('Biuro księgowe')
}));
it('renders correctly', () => {
const snap = renderer.create(<ContactScreen />).toJSON();
expect(snap).toMatchSnapshot();
});
But in this mock I need to mock entire object like this below:
{
"id": "xxxxxxxxxxxxxxxxxxxxxxxx",
"name": "Xxxxxxxxxxxx",
"nip": "xxxxxxxxxx",
"phone": null,
"city": "xxxxx",
"zip_code": "xx-xxx",
"street": "xxxxxxxxxxxxxxxxx",
"house_number": "xxxxxxx",
"room_number": "xx",
"email": "xxxxxxxxx",
"email_correspondence": "xxxxxxxxxxxxxxx"
}
Okay I figured it out, to mock an object I needed to wrap this in { } and write it like a json, code example below:
jest.mock('../../services', () => ({
useGetOfficeDataQuery: jest.fn().mockReturnValue({
id: "xxxxxxxxxxxxxxxxxxxxx",
name: "xxxxxxxxxx",
}),
}));
I'm struggling to go live. It's weird how something works in sandbox mode but then either there is no documented way to switch to production or it just does not work.
So here is what I got:
<template lang="pug">
.paypal
Spinner(:size="8" :thickness="3")
PaypalButtons.buttons(
:env="env"
:style="style"
:createOrder="order"
:onInit="init"
:onClick="validate"
:onApprove="approve"
:onError="error"
)
</template>
<script>
export default {
name: 'PayPal',
props: {
env: {
type: String,
default: 'sandbox',
validator: value => ['sandbox', 'production'].includes(value)
},
},
// ...
}
</script>
I've tried to set the env prop to production and removing it completely. I can not find any documentation on how to set the environment. I must miss something fundamental.
The error:
As I mentioned the sandbox mode works fine, but as soon as I go live (server side using PayPals production URL and client side with the corresponding env prop), I'm getting the following errors
Request
URL: https://www.sandbox.paypal.com/graphql?UpdateClientConfig.
BODY:
{
"query": "\n mutation UpdateClientConfig(\n $orderID : String!,\n $fundingSource : ButtonFundingSourceType!,\n $integrationArtifact : IntegrationArtifactType!,\n $userExperienceFlow : UserExperienceFlowType!,\n $productFlow : ProductFlowType!,\n $buttonSessionID : String\n ) {\n updateClientConfig(\n token: $orderID,\n fundingSource: $fundingSource,\n integrationArtifact: $integrationArtifact,\n userExperienceFlow: $userExperienceFlow,\n productFlow: $productFlow,\n buttonSessionID: $buttonSessionID\n )\n }\n ",
"variables": {
"orderID": "17884710UT885974F",
"fundingSource": "paypal",
"integrationArtifact": "PAYPAL_JS_SDK",
"userExperienceFlow": "INCONTEXT",
"productFlow": "SMART_PAYMENT_BUTTONS"
}
}
Response:
{
"data": {
"updateClientConfig": null
},
"errors": [
{
"_name": "RESOURCE_NOT_FOUND",
"checkpoints": [
"patchClientConfig"
],
"contingency": true,
"data": {
"message": "The specified resource does not exist."
},
"message": "RESOURCE_NOT_FOUND",
"meta": {},
"path": [
"updateClientConfig"
],
"statusCode": 200
}
],
"extensions": {
"correlationId": "464b1d56d4581",
"tracing": {
"duration": 98157194,
"endTime": "2021-09-06T16:29:45.133Z",
"execution": {
"resolvers": [
{
"duration": 96271082,
"fieldName": "updateClientConfig",
"parentType": "Mutation",
"path": [
"updateClientConfig"
],
"returnType": "Boolean",
"startOffset": 1222180
}
]
},
"startTime": "2021-09-06T16:29:45.035Z",
"version": 1
}
}
}
There is another request to https://www.sandbox.paypal.com/graphql?GetCheckoutDetails with a similar response.
As far as I can tell the request URL should not be www.sandbox.paypal...
I have also commented on an existing issue on GitHub, but I believe it will take too long to get an answer that way.
You are using a sandbox client ID.
Change to a live client ID, from an app in the "Live" tab of your Applications in developer.paypal.com
I am trying to update an array of objects in Vue.js. When trying to update the values of my location I am struggling to update the objects within an array.
When I log the objects out, I get this:
console.log(this.location) // {…}
console.log(this.location.additionalProperties); // [{…}, __ob__: Observer]
console.log(this.location.additionalProperties.integrations); // undefined
My additionalProperties object looks like this:
"additionalProperties": [
{
"integrations": [
{
"foo": {
"locationId": 123,
"example": "bar",
...
}
}
]
}
],
I am passing in my location as a props like this:
location: {
type: Object,
required: true,
default: () => ({}),
},
I know I am getting the location passed in correctly. I believe it is a syntax issue I am struggling with. I am trying to set my foo object to be something like this:
this.location.additionalProperties.integrations.foo = {
locationId: 456,
example: "testing",
somethingElse: "anotherValue"
}
Using the above, I'll get a version of cannot set foo of undefined. How can I update the object within the additionalProperties array?
Thank you for any suggestions!
additionalProperties is an array
"additionalProperties": [
{
"integrations": [
{
"foo": {
"locationId": 123,
"example": "bar",
...
}
}
]
}
],
this.location.additionalProperties[0].integrations.foo = ...
I have a computed property that pulls some data out of my vuex store like so:
computed: {...mapGetters(["allCategories"])},
Each category in this.allCategories looks like so:
{ "id": "123", "name": "Foo" }
I want to pull out every name field from this.allCategories before the component is mounted in put each name into an reactive data property called categoryNames.
How can I achieve this?
What I have tried so far is below:
beforeMount() {
for (let i = 0; i < this.allCategories.content.length; i++) {
var name = this.allCategories.content[i].name
this.categoryNames.push(name);
}
},
Which gives the following error:
Error in beforeMount hook: "TypeError: Cannot read property 'length' of undefined"
this.allCategories looks like so:
{
"content": [
{
"id": "efb038df-4bc9-4e31-a37a-e805c9d7294e",
"parentCategoryId": "8ffc214f-fff1-4433-aac9-34d13b4e06c5",
"name": "Foo"
},
{
"id": "5905d437-db2e-4f91-8172-c515577b86e9",
"parentCategoryId": "5905d437-db2e-4f91-8172-c515577b86e9",
"name": "Bar"
},
{
"id": "8ffc214f-fff1-4433-aac9-34d13b4e06c5",
"parentCategoryId": "8ffc214f-fff1-4433-aac9-34d13b4e06c5",
"name": "Baz"
}
],
"number": 0,
"size": 100,
"total": 3
}
You could use the created hook to call a vuex action that calls a vuex mutation that grabs a state, do your parsing and store the parsed data in a new array in state, then use a getter to grab the parsed array from state.
created() {
this.$store.dispatch('someAction');
},
computed: {
...mapGetters({
parsedArray: 'getParsedArray',
})
}
export const actions = {
someAction({ commit }) {
commit('SOME_MUTATION');
},
}
export const mutations = {
SOME_MUTATION(state) {
let data = state.originalData;
let parsedArray = [];
// Do parsing work here
state.parsedArray = parsedArray
},
}
export const getters = {
getParsedArray: state => {
return state.parsedArray;
},
}
How to update the cache, after creating new data?
Error message from Apollo
Store error: the application attempted to write an object with no provided id but the store already contains an id of UsersPermissionsUser:1 for this object. The selectionSet that was trying to be written is:
{
"kind": "Field",
"name": { "kind": "Name", "value": "user" },
"arguments": [],
"directives": [],
"selectionSet": {
"kind": "SelectionSet",
"selections": [
{ "kind": "Field", "name": { "kind": "Name", "value": "username" }, "arguments": [], "directives": [] },
{ "kind": "Field", "name": { "kind": "Name", "value": "__typename" } }
]
}
}
Nativescript-vue Front-end Details
1- Watch Book Mobile app in action on YouTube: https://youtu.be/sBM-ErjXWuw
2- Watch Question video for details on YouTube: https://youtu.be/wqvrcBRQpZg
{N}-vue AddBook.vue file
apolloClient
.mutate({
// Query
mutation: mutations.CREATE_BOOK,
// Parameters
variables: {
name: this.book.name,
year: this.book.year,
},
// HOW TO UPDATE
update: (store, { data }) => {
console.log("data ::::>> ", data.createBook.book);
const bookQuery = {
query: queries.ALL_BOOKS,
};
// TypeScript detail: instead of creating an interface
// I used any type access books property without compile errors.
const bookData:any = store.readQuery(bookQuery);
console.log('bookData :>> ', bookData);
// I pin-pointed data objects
// Instead of push(createBook) I've pushed data.createBook.book
bookData.books.push(data.createBook.book);
store.writeQuery({ ...bookQuery, data: bookData })
},
})
.then((data) => {
// I can even see ID in Result
console.log("new data.data id ::::: :>> ", data.data.createBook.book.id);
this.$navigateTo(App);
})
.catch((error) => {
// Error
console.error(error);
});
What are these "Book:9": { lines in the cache?
console.log store turns out:
"Book:9": {
"id": "9",
"name": "Hadi",
"year": "255",
"__typename": "Book"
},
"$ROOT_MUTATION.createBook({\"input\":{\"data\":{\"name\":\"Hadi\",\"year\":\"255\"}}})": {
You can see all front-end GitHub repo here
Download Android apk file
Our goal is to update the cache. Add Book Method is in here:
https://github.com/kaanguru/mutate-question/blob/c199f8dcc8e80e83abdbcde4811770b766befcb5/nativescript-vue/app/components/AddBook.vue#L39
Back-end details
However, this is a frontend question a running Strapi GraphQL Server is here: https://polar-badlands-01357.herokuapp.com/admin/
GraphQL Playground
USER: admin
PASSWORD: passw123
You can see GraphQL documentation
I have so much simple Strapi GrapQL Scheme:
If you want to test it using postman or insomnia you can use;
POST GraphQL Query URL: https://polar-badlands-01357.herokuapp.com/graphql
Bearer Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwiaWF0IjoxNTkwODI3MzE0LCJleHAiOjE1OTM0MTkzMTR9.WIK-f4dkwVAyIlP20v1PFoflpwGmRYgRrsQiRFgGdqg
NOTE: Don't get confused with $navigateTo() it's just a custom method of nativescript-vue.
It turns out;
all code was correct accept bookData.push(createBook);
// HOW TO UPDATE
update: (store, { data }) => {
console.log("data ::::>> ", data.createBook.book);
const bookQuery = {
query: queries.ALL_BOOKS,
};
// TypeScript detail: instead of creating an interface
// I used any type access books property without compile errors.
const bookData:any = store.readQuery(bookQuery);
console.log('bookData :>> ', bookData);
// I pin-pointed data objects
// Instead of push(createBook) I've pushed data.createBook.book
bookData.books.push(data.createBook.book);
store.writeQuery({ ...bookQuery, data: bookData })
},
})
Typescipt was helping
The point is; I shouldn't trust TypeScript errors, or at least I should read more about what it really says.
Typescript just asked me to be more specific while saying: Property 'push' does not exist on type 'unknown'
TypeScript was trying to tell me I need to be more specific while calling ROOT_MUTATION data. It said: Cannot find name 'createBook' But again I ignored it.
Solution Github Branch
https://github.com/kaanguru/mutate-question/tree/solution
Sources
how to update cache
Create interface for object Typescript