s.indexOf is not a function at Function.n.fromString - reactjs

I have no idea why I'm getting this error or from where is coming from because I think I'm not using that ?
I'm doing a firebase update after an user update a row from DataGrid MUI and I'm doing the update as I would normally do nothing different at all and it just jumps into that error.
I'm not sure if is an React error, JS error, Firebase error, MUI error. but I THINK is a firebase error because the path says so
This is what I was trying to do:
const [editRowsModel, setEditRowsModel] = React.useState({});
const [editRowData, setEditRowData] = React.useState({});
const handleEditRowsModelChange = React.useCallback(
(model) => {
const editedIds = Object.keys(model);
if (editedIds.length === 0) {
console.log(editRowData)
console.log(editRowData.uid)
console.log(editRowData.nombre)
console.log(editRowData.colegio)
console.log(editRowData.grado)
const temporalQuery = db.collection("usuarios").doc(user.uid).collection("estudiantes").doc(editRowData.uid);
temporalQuery.update({
nombre: editRowData.nombre,
colegio: editRowData.colegio,
grado: editRowData.grado
})
} else {
setEditRowData(model[editedIds[0]]);
}
setEditRowsModel(model);
},
[editRowData]
);
This is what the console.log shows up. I honestly don't see any error in the way I code it that's how I always do it, never had an issue before. First time I update from a nested collection though
This is how it looks in the firebase
And yes the user.uid also comes correctly

Found the issue is because the data comes with a whole string of information instead of just the value as I though it was coming.
All I had to do was to call the field + the value when I was using it.
Ej:
if I wanted the uid I had to call it editRowData.uid.value

the .doc(name) only accepts strings, so check if your user.uid is a string

Related

Why is my RTK Query "skip" parameter not working?

What I'm trying to do is fetch an array of objects, then fetch data related to the first object in the array.
const progress = useSelector(state => state.progress);
const appInfo = useSelector(state => state.appInfo);
const {
data: steps,
isLoading: isStepsLoading,
isSuccess: isStepsSuccess
} = useGetAllStepsQuery()
const {
data: questions
} = useGetQuestionsQuery({app_id: appInfo.id, step_parameter: steps[progress.currentStepIndex].step_parameter}, {skip: isStepsLoading})
The problem I'm having is that attempting to extract the step_parameter from the steps array is throwing a Cannot read properties of undefined (reading '0') error: in other words, it's as if the useGetQuestionsQuery is being called before the useGetAllStepsQuery is finished. I've added a skip parameter to the request, per this answer, and tried various values with it (e.g. !isStepsSuccess), none of them resolve this problem. I've also tried assigning the step_parameter conditionally, like this:
step_parameter: isStepsSuccess ? steps[progress.currentStepIndex].step_parameter : ''
Which does prevent the error, but it also appears to prevent the questions call from ever being made. Any help would be appreciated!

The order for inlineStyleRanges is wrong

I have a react application that allows our users to input data into the Editor component provided by draft-js. I made my own toolbar component our user could interact with by passing functions that update the EditorState. I also need to be able to save the EditorState contents to our database. We're able to save the database by using the ff code:
const serialized = JSON.stringify(
convertToRaw(editorState.getCurrentContent())
);
saveStringToDatabase(serialized);
and are able to restore the values from the database using
const [editorState, setEditorState] = useState(() => {
if (!serializedEditorState) {
return EditorState.createEmpty();
}
const contentState = convertFromRaw(JSON.parse(serializedEditorState));
return EditorState.createWithContent(contentState);
});
. All is good in the user interacting with the Editor component from the front-end.
Now the problem is when I try to restore the data saved in the database to the front-end, I get a wrong snapshot of the state editor. I'm suspecting it's because the result of the convertToRaw() function has the wrong order for blocks[index].inlineStyleRanges. In my attached screenshot, index 3 of inlineStyleRanges of the blocks object should be index 4 and index 4 should be in index 3. I think I might be using the wrong functions for updating the EditorState but can't confirm as I do not see any other resources describing the actual correct way to update EditorState. We update the editor state using the ff code:
const removedInlineStyle = Modifier.removeInlineStyle(
editorState.getCurrentContent(),
newSelection,
inlineStyle,
);
const newInlineStyle = Modifier.applyInlineStyle(
removedInlineStyle,
newSelection,
inlineStyle,
);
const newEditorState = EditorState.push(
EditorState.acceptSelection(editorState, newSelection),
newInlineStyle,
'change-inline-style',
);
setEditorState(newEditorState);
here is a github issue of someone else that's experiencing something like mine. enter image description here

Why I cannot map data?

I'm trying to map "historicData" and put them in the labels of chart but it gives me error,"u cannot map the undefined".
So,Error is historicData is undefined .When I console.log(historicData),there is an array data.
This is my Code.
https://github.com/Saithiha24/React-Crypto-Beast/blob/master/src/Components/CoinInfo.js
I try to solve this for 2 days still can't find the answer. Please help me.
I think the problem is that historicData is initially undefined, and while waiting for the async call to complete and give historicData a value, you get the error. I suggest you change this
const [historicData, setHistoricData] = useState();
to this
const [historicData, setHistoricData] = useState([]);
so historicData is originally an empty array instead of undefined. You can also change the definition of data likes this
const data = {
labels: historicData ? historicData.map((coin) => {
//your code
}) : []}
so that if historicData is undefined, you don't try to map, just assign an empty array to labels.

setState is not updating state at all

I cant figure out why my setStock function is not updating the state and not causing a re-render, while I have several other functions working just fine.
const addToStockOperation = async (addOperation) => {
const payload = {
...
};
const jwtToken = {
...
};
const addToStockOperationResult = await axios.put(`${apiEndpoint}/stock/addtoitem`, payload, jwtToken);
setStock((prevStock) => {
const indexOfModifiedStock = prevStock.findIndex((stock) => stock._id === addOperation.id);
console.log(prevStock[indexOfModifiedStock].operations.added.length);
prevStock[indexOfModifiedStock].operations.added = addToStockOperationResult.data.operations.added;
console.log(prevStock[indexOfModifiedStock].operations.added.length);
return prevStock;
});
};
Both console logs confirm that the modification of prevStock did happen, as the second console.log shows a length of +1 compared to the previous length, so that indicates that the desired part of prevStock was indeed updated, however, a re-render is not caused.
I have also tried making a copy of prevStock const stockCopy = {...prevStock}; and modifying the copy and returning the copy, but no change.
I have also tried simply to return 1; just to see if a re-render will get triggered, still nothing.
I have a few other similar functions that are working just fine and are causing a re-render as expected:
This one is working just fine for setting products:
const setProductsWrapper = async (product) => {
const addProductResult = await axios.post(
`${apiEndpoint}/product/one`,
payload,
token
);
addProductResult.data.name === product.name &&
setProducts((prevProducts) => [addProductResult.data, ...prevProducts]);
};
EDIT: I found the issue, silly me, stock is an array return [...stockCopy]; after modifying the copy, worked.
Returning prevStock is never going to work because it is the current state array (i.e. has reference equality with it) - you need to return a new array for a new render to be triggered. However, it seems likely that an issue is also arising with mutated state.
You're on the way there when you create the copy const stockCopy = [...prevStock], but the problem is that this only copies the state array to one level of depth. Any objects nested inside it, like .operations, will retain their reference equality to the objects in the original state array.
Mutating them directly means that when you return your copy, any effects which rely on a difference in reference equality between these sub-objects will not run because they are already equal. There is no diff-ing to be done.
To fix this you will have to deeply copy the relevant parts of the tree:
setStock((prevStock) => {
const stockCopy = [...prevStock];
const stockIndex = stockCopy.findIndex((stock) => stock._id === addOperation.id);
stockCopy[stockIndex] = {
...stockCopy[stockIndex],
operations: {
...stockCopy[stockIndex].operations,
added: addToStockOperationResult.data.operations.added
}
};
return stockCopy;
});
State mutation sandbox
This can get quite annoying (and potentially expensive) when the data structure is large enough. It's always better to avoid structures like this in immutable state if you can help it. Of course that's often not the case and there are tools to help deal with immutability that can cut down on bloated code if it starts to become an issue.

GraphQL Automatic refetch on empty responses

I want to randomize movies from theMovieDB API. First I send a request to access the ID of the latest entry:
const { loading: loadingLatest, error: errorLatest, data: latestData, refetch: refetchLatest } = useQuery(
LATEST_MOVIE_QUERY
);
Then I want to fetch data from a randomly selected ID between 1 and the number of the latest id. Using a variable dependant on the first query seems to break the app, so for now I'm just using the same movie every time upon mounting the component:
const [
movieState,
setMovieState
] = useState(120);
const { loading, error, data, refetch } = useQuery(ONE_MOVIE_BY_ID_QUERY, {
variables : { movieId: movieState },
skip : !latestData
});
I want to press a button to fetch a new random movie, but the problem is that many of the IDs in the API lead to deleted entries and then I get an error back. I want to keep refetching until I get a good response back but I have no idea to implement it. Right now my randomize function just looks like this:
const randomizeClick = () => {
let mostRecentID = latestData.latestMovie.id;
setMovieState(Math.floor(Math.random() * mostRecentID));
};
I'd be grateful if someone can help me how to implement this.
I think what you needs is the "useLazyQuery" functionality of Apollo. You can find more information about it here: https://www.apollographql.com/docs/react/data/queries/#executing-queries-manually
With useLazyQuery you can change your variables easily and this is meant to be fired after a certain event (click or something similar). The useQuery functionality will be loaded when the component is mounted.

Resources