handling error trying to set key of immutable and frozen object - react-native

i have the following object in a state:
App.js
const data = {name: 'John', status:'employeed' };
const [manager, updateManager] = useState(data);
const updateStatus = async () =>{
await service.setStatus(manager);
}
setStatus does modify the manager directly, which I think is the source of the problem
service.js
setStatus(manager){
manager.status = 'employeed';
}
so I modified the call to send a copy of the manager object and return a new object but still I get the error
you tried to modify 'status' key of an immutable object.
here is my new change
App.js
const updateStatus = async () =>{
const g = await service.setStatus({...manager});
updateManager(g);
}
service.js
setStatus(manager){
manager.status = 'employeed';
return manager;
}

Why has this function to be async?
const updateStatus = async () =>{
await service.setStatus(manager);
}
This return a new/updated object but it won‘t do any permanent changes.
setStatus(manager){
return {…manager,status: 'employeed'};
}
Does the problem after your last changes persists?
You should pass a callback like this:
const updateStatus = (manager) => {
service.setStatus(()=> updateManager({
...manager,
status: 'employeed'
}));
Service.js
setStatus(updateManager){
updateManager(manager);
}

Related

Hot to handle async props in vue 3 composition API

Parent compoment:
const { getGroup, removePubli, removeTablet, loadTotal, error } = useGroups();
const group = ref({});
getGroup(group_id).then((g) => {
group.value = g;
});
Child component:
const { group } = defineProps({
group: {
type: Object,
default: {},
},
});
Given the prop above, which is fetched by an async axios call, when I try to use it in a chield component it is undefined or a promise.
I've already tried to put an async inside onMounted hook but it doesn't work.
getGroup does it:
const getGroup = async (id) => {
const r = await api.get(`/api/v1/groups/${id}`);
if (r?.status !== 200) error.value = "Falhou";
return r.data;
};
I want to await it before the code continues or find a way to do something when the promise resolves itself.
I don't see in your code any await. Use await instead of .then!
<script setup>
const { getGroup, removePubli, removeTablet, loadTotal, error } = useGroups();
const group = ref({})
const result = await getGroup(someId)
group.value = result.data // or what ever
</script>

NuxtJS dispatch is not loading data

I've been struggling for 5 hours with the following issue.
I have a service file where I have API calls using Axios. In the store, I have an action that uses the service to pull a list of schools, then I commit the data to the mutations. If I console log the data on the mutation object, it works correctly and shows the data. However, when I call dispatch from the component inside the onMounted hook, I get an empty object. Any help is greatly appreciated. (see the code below)
store/schools.js
export const state = () => ({
mySchools: []
});
export const mutations = {
getSchools(state, data) {
state.schools = data;
console.log(state.schools); // works;
}
};
export const actions = {
async getMySchools({ commit }) {
await this.$getSchools().then(response => {
commit("getSchools", response.data);
});
}
};
portal/dashboard.vue
import {onMounted, ref, useStore} from "#nuxtjs/composition-api";
export default {
layout: 'portal',
setup() {
const store = useStore();
const schools = ref([]);
onMounted(async() => {
await store.dispatch('schools/getMySchools'); // is not pulling data
schools.value = store.state.schools.mySchools;
console.log(schools); // empty
});
return {
schools
}
}
};
Thank you
You shouldn't use await with then
try this
async getMySchools({ commit }) {
const response = await this.$getSchools();
commit("getSchools", response.data);
}
I'm assuming that your this.$getSchools() actually works since I'm not sure what that is and it's not part of the code

Spy on window function with testcafe

I want to test with testcafe if a function on a window object is executed with certain parameters. Is it possible with Testcafe?
The function call looks like this:
window.myObject.myFunction({customObject: true});
You can use the ClientFunction API to create a spy function in a window object. Please look at the following test example:
import { ClientFunction } from 'testcafe';
fixture `New Fixture`
.page `https://cf51n.csb.app/`;
const spyOn = ClientFunction(() => {
// Create an array where we store information about `myFunction` calls
window.myFunctionSpyData = [];
// Store the original `myFunction` value
window.orirginalFunction = window.myObject.myFunction;
window.myObject.myFunction = function() {
// Save data about the current call
window.myFunctionSpyData.push(...arguments);
// Call the original `myFunction` value
window.orirginalFunction(...arguments);
}
});
const getSpyData = ClientFunction(() => {
// Retrieve data about myFunction calls from client
return window.myFunctionSpyData;
});
const spyOff = ClientFunction(() => {
// Restore the original myFunction value
window.myObject.myFunction = window.orirginalFunction;
delete window.spyData;
});
test('New Test', async t => {
await spyOn();
await t.click('#btn');
const data = await getSpyData();
await spyOff();
await t
.expect(data.length).eql(2)
.expect(data[0]).eql('1')
.expect(data[1]).eql('2');
});

React-Native Async Storage returns weird object with correct value in two consecutive lines

I've researched this and not found a similar case answered, at my whits end.
I have the following code to get an item from AsyncStorage, which returns the correct value when I log it on the console, but the function's return value is: {\"_40\":0,\"_65\":1,\"_55\":\"Nick\",\"_72\":null}
const getData = async () => {
try {
const value = await AsyncStorage.getItem('userDetails');
if(value !== null) {
const wsi_user = await JSON.parse(value);
console.log("userName: " + wsi_user.userName); // returns "Nick"
return wsi_user.userName; // returns {\"_40\":0,\"_65\":1,\"_55\":\"Nick\",\"_72\":null}
}
} catch(e) {
letter = "D";
}
}
I've seen similar articles where people mention that the promise needs to resolve and I get that, but my result is within the outputted weird object, AND, my result is correct when logged to console the line before return.
Please advise. No clue how to fix this.
You can call this function like:
const result = await getData()
Also, you don't need the await before JSON.parse() as it is synchronous.
Maybe you can use react-native-easy-app, through which you can access AsyncStorage synchronously, and can also store and retrieve objects, strings or Boolean data
import { XStorage } from 'react-native-easy-app';
import { AsyncStorage } from 'react-native';
// or import AsyncStorage from '#react-native-community/async-storage';
export const RNStorage = { userInfo: undefined };
const initCallback = () => {
// From now on, you can write or read the variables in RNStorage synchronously
// equal to [ await AsyncStorage.setItem('userInfo',JSON.stringify({ name:'rufeng', age:30})) ]
RNStorage.userInfo = {name: 'rufeng', age: 30};
};
XStorage.initStorage(RNStorage, AsyncStorage, initCallback);
You need to convert the object to a string before saving it in the async storage AsyncStorage.setItem(key, JSON.stringify(data));
Example:
export const setStorageItem = async (key: string, data: any): Promise<void> => {
return AsyncStorage.setItem(key, JSON.stringify(data));
};
export const getStorageItem = async <T>(key: string): Promise<T | null> => {
const item = await AsyncStorage.getItem(key);
if (item) {
return JSON.parse(item);
}
return null;
};
Example from the docs

redux-thunk: actions are not dispatching

I am trying to build an app in react native that is suppose to take take two inputs by a user and then make a query to an api and get information about the two inputs. I have been having trouble with redux and redux-thunk and specifically with async actions.
This is the code in my app that i am specifically having trouble with
export const fetchData = url => {
console.log("start Fetching");
return async dispatch => { // this is where the problem is
dispatch(fetchingRequest());
try {
const response = await fetch("https://randomuser.me/api/?results=10");
const json = await response.text();
if (response.ok) {
dispatch(fetchingSuccess(json));
console.log("JSON", json);
} else {
console.log("fetch did not resolve");
}
} catch (error) {
dispatch(fetchingFailure(error));
}
};
console.log("Fetched data");
};
Upon debugging the function, I have ended with finding that when the fetchData function is called the function will execute but the async dispatch that is being returned has undefined behavior.
The output in the debugger when the function is called should be
start Fetching
JSON file information/Error
but the output in the debugger is actually
start Fetching
This is the function in which fetchData is called in
_onPress = () => {
let url = "https://randomuser.me/api/?results=10";
fetchData(url);
console.log("should have fetched");
};
this is the mapDispatchToProps function that I have added. The problem is i do not know what to add inside the function.
const mapStatetoDispatch = (url, dispatch) => {
return {dispatch(fetchData(url))}; // do not know what to place in body of function
};
i have connected it in the component with
export default connect(
mapStateToProps,
mapDispatchToProps
)(App);
these are the action creators that I import, if needed
import {
fetchingSuccess,
fetchingRequest,
fetchingFailure,
fetchData
} from "../data/redux/actions/appActions.js";
Assuming you have added redux-thunk as a middleware, it looks like the errors are here:
_onPress = () => {
const { fetchData } = this.props;
let url = "https://randomuser.me/api/?results=10";
fetchData(url);
console.log("should have fetched");
};
and
const mapStatetoDispatch = dispatch => ({
fetchData: url => dispatch(fetchData(url)),
}};