How to fix First Character Only bug - reactjs

I am facing a complex bug where two json fields, the name and the description, only show their first character on a table every now and then randomly for no apparent reason. Has anyone ran into this issue? Attached screenshots of behavior below.
My web stack consists of a golang api get request being called using axios by a react frontend where I feed a react table component.
Table with first character only bug
Table with expected result
Axios Call
fetchMaintenanceEventsData() {
let parent = this;
console.log('Fetching Maintenance Events Data');
this.setState({
maintenanceEventsData: [],
maintenanceEventsDataLoading: true
});
axios.get(`server-status/events`)
.then((res) => {
// console.log('res.data: ', res.data);
parent.setState({
maintenanceEventsData: res.data,
maintenanceEventsDataLoading: false
});
})
.catch((error) => {
console.log("Error:", error);
parent.setState({
maintenanceEventsDataLoading: false
})
});
}
I expect the table fields to display completely 100% of the time.

Related

Sanity Query Does Not Return Updated Data Consistently

I have a "film" category in my Sanity database which has an array of comments.
In my UI, I present a pic of the film with the comments listed below the film. I created a function to add comments to the film and then fetch the film with the comments.
As you can see, in my addCommentToFilm function, I commit a patch query to Sanity to add a comment to the film; the commit returns a promise. I console log the response from Sanity, and it has the updated comments array (including the comment I just added). I then call a function to fetch the film from Sanity, but the film's comments array does not always have the last comment added: Sometimes it does, and sometimes I have to call the function a few times until I receive the updated array with the comment most recently added.
Does anyone know why this happens and whether there is a way to receive the updated list of comments consistently?
`
const addCommentToFilm = (filmId) => {
client
.patch(filmId)
.setIfMissing({ comments: [] })
.insert('after', 'comments[-1]', [{
comment,
_key: uuidV4(),
postedBy: {
_type: 'postedBy',
_ref: user._id,
}
}])
.commit()
.then((res) => {
console.log(res); // I get the film with the comments, including the comment I just added
fetchFilms(filmId);
})
.catch((error) => {
console.log('Comment post error: ', error);
})
}
const fetchFilm = (filmId) => {
client
.fetch(`*[_type == "film" && _id == "${filmId}"]`)
.then((res) => console.log(res)) // I get the film with the comments, sometimes with and sometimes without the comment I just added
}
`
OK, received this information on the Sanity help thread on Slack:
This might be related to me setting 'useCdn: true' in my client.js file, as there is a slight delay between purging/revalidating.
Link to docs: https://www.sanity.io/docs/api-cdn#da702944cd86
Once I changed my setting to 'useCdn: false' the problem was solved, and now I am getting the updated data from the database in response to my query.
Great support from Sanity on Slack!

Invalid character found in method name error when fetching an api using React

I have implemented a table using ag-grid react. I fetch data from an api to fill in that table.
const getDataForTable = async () => {
try {
//apis to fetch the data
setGridData(apiData);
}
catch (err) {
console.error(err);
}
}
useEffect(() => {
getDataForTable();
}, []);
Now, I have also created an onClick method for deleting selected rows of the table. I am removing the rows from api as well. Once the rows are deleted, I just want to refresh the grid with updated data. Currently it only works if I explicitly reload the page.
const onClickRemoveRowsByIds = async () => {
selectedRows.forEach(d => {
listOfIds.push(d.Id);
});
if (window.confirm("Are you sure ?")) {
await listOfIds.map((ele) => removeActiveList(ele));
getDataForTable()
}
}
But when I make a call to getDataForTable function, I get bad request error for the apis. On looking at the reponse body of the api : I get Invalid character found in method name. HTTP method names must be tokens. The authToken and rest of the information remains same but still fetch is not working again. Am I missing some step, or doing it completely wrong? The delete works fine, just the refresh is not happening.

Spread Operator not copying results in React

I am trying to update setState in a for loop, but for some reason state isn't being copied it's just being replaced. There should be 2 clients, instead I am getting one. Can anyone tell me why this is happening? The console.log is returning both clients.
const handleViewClients = () => {
for (let i = 0; i < clients.length; i++) {
console.log(clients[i].clientid);
fetch("http://localhost:3005/all-clients/" + clients[i].clientid)
.then((response) => response.json())
.then((result) => {
console.log(result);
setBarbersClient({
...barbersClient,
client: result,
});
});
}
};
I have also tried this... The console.log is returning what I need
Promise.all(
clients.map((client) =>
fetch("http://localhost:3005/all-clients/" + client.clientid)
)
)
.then((resp) => resp.json())
.then((result) => {
console.log(result.username)
setBarbersClient({
...barbersClient,
client: result,
});
});
Here is the route from the server side
app.get("/all-clients/:clientid", (req, res) => {
db.NewClientsx.findOne({
where: {
id: req.params.clientid,
},
}).then((response) => {
res.json(response);
});
});
There some fundamental concepts of sync vs. async code that you aren't accounting for here. State changing (and fetching) is asynchronous, so it won't run until after this synchronous loop has finished being executed (during which the state value will remain unchanged). Also, it's a bad idea to change state in a loop, for this reason and others.
Fetch all the clients, then do one state change at the end with all the fetched data. You can utilise things like Promise.all and Promise.spread to achieve this. Here's an example of doing multiple fetches then dealing with the results in one batch: How can I fetch an array of URLs with Promise.all?
You're making two distinct mistakes of which either is enough to cause the behaviour you're seeing.
1. You're overwriting the client property.
Every time you call the setter function you're overwriting the previous value of the client property. You'll need some data structure that supports multiple values like a map:
setBarbersClient({
...barbersClient,
clients: {
...barbersClient.clients,
[result.id]: result
},
});
You will need to change your render logic somewhat to accomodate the new data structure.
2. You're using a stale reference.
When you access barbersClient its setter may have already been called with a different value and your reference to it still refers to the value of the previous run of the render function. You can make sure your reference is fresh by using a set state action callback.
setBarbersClient(previousValue => {
...previousValue,
clients: {
...previousValue.clients,
[result.id]: result
},
});
previousValue will never be stale inside the set state action function body.

How to have a server return a remote json object to client? react/express/web3

I'm using web3 to send a transaction to Ethereum. My express server logs the block, transactionHash, etc. data as a json object. I need the json returned to the client.
This question is running the risk of repeating a previous question, but I believe that it is more refined, to the point, and ultimately a different question. These previous threads have helped me remove several errors from the code and zero in on what is actually happening.
How to return json data to a react state?
How to await a json return value (the return takes at least 30 seconds) before logging it? javascript/react/express
How to set state of a react component with a specific item from a returned json object?
The specific code that is returning a blank value instead of the json object is:
web3.eth
.sendSignedTransaction("0x" + serializedTx.toString("hex"))
.on("receipt", console.log, res.json());
Client Code:
axios
.post("http://ec2-54-67-28-69.us-west-1.compute.amazonaws.com:3000/")
.then(response => console.log(response.data, payment))
.catch(function(error) {
console.log(error);
})
I somehow need to get the json object inside the res.json() but putting it inside the function () does not work. Any suggestions?
Thanks!
Edit. I am pretty sure I need to use something from this:
web3.eth.sendTransaction({from: '0x123...', data: '0x432...'})
.once('transactionHash', function(hash){ ... })
.once('receipt', function(receipt){ ... })
.on('confirmation', function(confNumber, receipt){ ... })
.on('error', function(error){ ... })
.then(function(receipt){
// will be fired once the receipt is mined
});
Try this:
web3.eth
.sendSignedTransaction("0x" + serializedTx.toString("hex"))
.on("receipt", res.json);
The way you did it res.json() was called without parameters.

Showing loading indicator while writing data to Firestore

I have a question regarding the fact, that i cant seem to figure out how to show a loader when updating firestore.
I have provided this following example, but dont mind the things i have used in the example. The point is, that I cant seem to figure out how to show a loading indicator until all creations or updates are completely finished.
If i try to setstate before and after the firestore call, the spinner will only appear in 1 second, since the actual call is running in the background (asynchronously i think) when it is updating the firestore.
Can anyone please help me out?
Thanks in advance.
array.forEach(itemInArray => {
db.where(test, '==', itemInArray.test )get()
.then((result) => {
// try to update doc first
db.doc(result.docs[0].id).update({
test: 'test'
});
})
// update successfull
.then(() => console.log('Document exists! We have updated the current one'))
// If the update failed, we create new doc
.catch((err) => {
console.log('Created document);
db.doc().set({
test: 'test'
});
});
});
As we discussed in the chat, if your database operations need to be sequential, you could do something like this:
showSpinner();
updateFirstThing()
.then(() => updateSecondThing())
.then(() => updateThirdThing())
.catch(err => handlerError(err))
.finally(() => hideSpinner());
If some of the operations can be parallel, you'd need to consider using Promise.all to make sure the spinner is hidden when all of the promises are fulfilled (or there was an error).

Resources