React Firebase Axios : problem with saving the data to Firebase - reactjs

I am trying to create a Translation app in which I send the text to the api and then i receive the translation back with a text typing effect.
The problem arise when I save the words that I receive to Firebase with debounce function. It always only save the initial part of the translation received (let's say that I get a translation of 100 words, it saves only the first 10) and I can't really figure out why.
This is the function that I use to send the text to the api and then receive the translation back.
handleClick(e) {
e.preventDefault();
let body = {
prompt: this.state.input
};
let thisComponent = this;
axios.post(TRANSLATE_API_URL, body).then(({ data: { text } }) => {
let wordDelay = 100 // Add a word every 100ms
let timerDelay = 0
text.split(" ")
.forEach(word => {
setTimeout(function(){
thisComponent.setState({ input: thisComponent.state.input + " " + word });
},timerDelay);
timerDelay += wordDelay;
});
//Calling Firebase function
this.updateBody(this.state.input);
});
}
And this is the code that I use to save data to Firebase .
updateBody = async (val) => {
await this.setState({ input: val });
await this.setState({ wordsCounted :val.split(' ').length });
await this.setState({charactersCounted : val.length })
/*assign the number of words inside the textarea to the variable wordsCounted*/
this.update();
};
update = debounce(() => {
this.props.noteUpdate(this.state.id, {
body: this.state.input,
})
}, 750);
The only explanation I have given myself is probably a problem with asynch and await.

Related

how can i delete multiples request at the same time using axios and an array of URL

im doing an app and the first code is working deleting a "task" in my API, but in my app each task have a checkbox input, so, i want to delete all the tasks that are checked.
i used this code to delete single task with a button.
const baseURLtasksId = `https://63cf2168e52f5878299ab5e2.mockapi.io/api/users/${userid}/tasks/${taskId}`
axios.delete(baseURLtasksId, { done: true }).then()
}
ArrayUrlById this is an array of all the URL's that are checked
const deleteAll = () => {
let ArrayUrlById = []
ArrayUrlById = isChecked.map((cId) => {
let arrayURL = `https://63cf2168e52f5878299ab5e2.mockapi.io/api/users/${userid}/tasks/${cId}`
return arrayURL
})
console.log(ArrayUrlById); // here i have an array of the URL
// i need to delete now multiples tasks, using an array of URL and sending {done:true} for each one
}
i tried with this code, but not working properly, beacuse never delete all of them, even in the console send all the delete request to the endpoint with a 200 status, but after i refresg the website, is not deleting all of them that are checked
const deleteAll = () => {
let ArrayUrlById = []
console.log('aqui');
ArrayUrlById = isChecked.map((c) => {
let arrayURL = `https://63cf2168e52f5878299ab5e2.mockapi.io/api/users/${userid}/tasks/${c}`
return arrayURL
})
console.log(ArrayUrlById);
const requests = ArrayUrlById.map(url => axios.delete(url));
axios.all(requests)
.then(responses => {
responses.forEach(response => console.log(response.data));
})
.catch(error => {
console.log(error);
})
}
enter image description here

React native: how do I wait for a state to be set, before I call another state related operation?

I am writing a chat app. Users can search for other users, and then press the "Message" button. Then I navigate to ChatScreen.js. If both users have been messaging each other, I set the chatId variable accordingly. If they have not messaged each other before I dont create chatId, until the ery first message has been sent. When the first message is sent, I first, create new chat, store its properties (user ids, chatId, etc) in my db and then I sent the first message. The problem is that I store chatId as a state variable, and when I create the chat I call setChatId(id). setChatId() is not synchronous call, so by the time when I need to send message with sendText(text, chatId); my chatId is undefined even though I have already created a chat and I have called setChatId.
How can I avoid this error? Ofc, I can check if chatId == undefined then calling sendText(text, id), otherwise calling sendText(text, chatId). Is there a better/neath way to avoid the undefined check?
Here is part of my code:
...
import {
createChat,
} from "./actions";
...
function ChatScreen(props) {
...
const [chatId, setChatId] = useState(props.route.params.chatId);
...
const setupChat = async () => {
try {
await createChat(user.id, setChatId);
props.fetchUserChats();
} catch (error) {
console.error("Error creating chat: ", error);
}
};
async function handleSend(messages) {
if (!chatId) {
// creating chat
await setupChat();
}
const text = messages[0].text ? messages[0].text : null;
const imageUrl = messages[0].image ? messages[0].image : null;
const videoUrl = messages[0].video ? messages[0].video : null;
const location = messages[0].location ? messages[0].location : null;
//assuming chatId is already setup but it is not
if (imageUrl) {
sendImage(imageUrl, chatId, setSendImageError);
} else if (location) {
sendLocation(location, chatId, setLocationError);
} else if (videoUrl) {
sendVideo(videoUrl, chatId, setSendImageError);
} else {
sendText(text, chatId);
}
}
...
}
My createChat function from actions.js file
export async function createChat(otherUid, setChatId) {
let chatId = firebase.auth().currentUser.uid + "_" + otherUid;
await firebase
.firestore()
.collection("Chats")
.doc(chatId)
.set({
users: [firebase.auth().currentUser.uid, otherUid],
lastMessage: "Send the first message",
lastMessageTimestamp: firebase.firestore.FieldValue.serverTimestamp(),
})
.then(() => {
console.log("doc ref for creatign new chat: ", chatId);
setChatId(chatId);
})
.catch((error) => {
console.error("Error creating chat: ", error);
});
}
Instead of using a state variable, I would advise you to use useRef(). This would be a good solution to your problem.Eg Define it this way
const chatId = useRef(null),
then set it this way chatId.current = yourChatId
and get it this way chatId.current. I hope this solves your problem

How to push multiple images in an array?

I'm creating a React Native application. I want to create an image array because I need to upload them to the server. But when I upload multiple images they are not storing like an array. every time the imagesQueue array has only one image.
my code as follows.
const [filePath, setFilePath] = useState({
imagesQueue: []
});
const chooseFile = () => {
const options = {
title: 'Select an option',
storageOptions: {
skipBackup: true,
path: 'images',
},
};
ImagePicker.showImagePicker(options, (response) => {
// console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled image picker');
} else if (response.error) {
console.log('ImagePicker Error: ', response.error);
} else {
// let source = response;
// You can also display the image using data:
let source = {
uri: 'data:image/jpeg;base64,' + response.data
};
setFilePath({
...filePath,
imagesQueue: [source],
});
console.log("stored item : " + filePath.imagesQueue);
}
});
};
How to store multiple images in the same state. Thanks in advance.
the data probably will store in formData - it's easy format for later passing it to BE.
firstly You need store somewhere those data:
const [selectedFiles, setSelectedFiles] = useState([]);
Later there is possibility to use .concat() - that function connects 2 arrays:
setSelectedFiles(((prevState) => prevState.concat(fileData)));
And in the last step, You need to pass those data to Your form:
const formData = new FormData();
for (let i = 0; i < selectedFiles.length; i++) {
formData.append('Files', selectedFiles[i].File);
}

Fetching data from mongoose

I'm trying to fetching my data from mongo to the client-side to react.
I succeed to set the state of the component to the correct fields from the endpoint API of my DB.
But when I want to print my state to see if it is working the console print my an empty object although the state change and I see it in the console.[enter image description here][1]
getDataFromDb = () => {
const req = new Request('http://localhost:5000/family',{
method: 'GET',
cache: 'default'
});
fetch(req).then(res=>{
return res.json();
}).then(data=>{
console.log(data);
this.setState({
rooms: data
});
console.log(this.state.rooms);
}).
catch(err=>{
console("Error: " + err);
});
};
componentDidMount() {
this.getDataFromDb().then(result => this.setState({rooms: result}));
//let rooms = this.formatData(this.getDataFromDb());
//let featuredRooms = ...rooms.filter(room => room.featured===true);
//let maxPrice = Math.max(...rooms.map(item=>item.price));
//let maxSize = Math.max(...rooms.map(item=>item.size));
//new code:
let featuredRooms = this.state.rooms.filter(room=>room.featured===true);
let maxPrice = Math.max(this.state.rooms.map(item => item.price));
let maxSize = Math.max(this.state.rooms.map(item=> item.size));
this.setState({
// old code ---> rooms,
//rooms,
featuredRooms,
sortRooms: this.state.rooms,
//old code
//sortedRooms:rooms,
loading:false,
price:maxPrice,
maxPrice,
maxSize
});
this.printData();
}
In react, setState is an async function. Printing the state (just after changing it) will not give you the latest state. If you want to trigger a function after setting the state you can do the following:
this.setState({
// old code ---> rooms,
//rooms,
featuredRooms,
sortRooms: this.state.rooms,
//old code
//sortedRooms:rooms,
loading:false,
price:maxPrice,
maxPrice,
maxSize
}, () => { this.printData(); });

How to take data from array? Can't take data in const from array

This is data array protocols
https://dropmefiles.com/MchK8 this is my code.
Why selectMembers is empty and when I directly do the protocol.Members, it issues data?
How can i use Selectedmembers?
componentDidMount() {
const {members} = this.props;
const selectedMembers = [];
this.getProtocolsDetails(this.props.protocol.id);
this.setState({isLoading: true});
console.log(protocol);
// if (!isNull(protocol.members) && protocol.members.length) {
// protocol.members.map(member => {
// selectedMembers.push({
// label: member.fullName,
// value: member.code
// });
// });
// }
}
getProtocolsDetails(id) {
ProtoApi.getProtocolById(id)
.then(protocol => {
this.setState({protocol}, () => {
});
})
.catch(() => {
});
}
<AutoComplete label="Участники"
placeholder="Выберите участников"
searchApi={this.onSearchMembers}
onUpdate={this.onChooseMember}
onDeleteItem={this.onDeleteMember}
multiple={true}
dataSource={selectedMembers}
error={!isUndefined(errors.members)}
helperText={!isUndefined(errors.members) ? errors.members : null}/>
I want to take and show data when i edit this element members in selectedMembers from array looks like empty but it show like this if i have doesnt empty selectedMembers
The first after request you save data in this.state.protocol, but display in console.log just protocol.
The second componentDidMount will not wait api response, you should use componentDidUpdate or replace logic in getProtocolsDetails

Resources