Add debounce in React.js - javascript

This function is performed on the onChange action. I want only what is under the comment to debounce on 1s. How can I accomplish this?
onChange = (event, { newValue }) => {
this.setState({
value: newValue,
}, () => {
if (this.state.value.length !== 26) {
// this debounce \/
this.Auth.getUsersData(newValue).then(res => {
if (res) {
this.setState({
accountBills: res,
});
}
});
};
});
}

Just extract that code into a new method and wrap it in _.debounce:
import {debounce} from 'lodash';
getUserData = debounce(newValue => this.Auth.getUsersData(newValue)
.then(res => {
if (res) { this.setState({ accountBills: res }) }
})
, 1000);
onChange = (event, { newValue }) => {
this.setState({
value: newValue,
}, () => {
if (this.state.value.length !== 26) {
this.getUserData(newValue);
}
});
}

Related

Array is empty after api call using vuejs3

I'm using vue-js and i encountered this problem where i call a get all api and then store it in an array. The logic works perfectly fine in the first component, however when i copied literally the exact same code and pasted it in a second component the call for some reason returns an empty array instead of the array of users. Here is the component
import UsersInServiceCenterService from "../services/UsersInServiceCenterService";
import UserService from "../services/UserService";
export default {
name: "service center",
data() {
return {
currentServiceCenter: null,
message: '',
listOfSpecificServiceCenter1: [],
listOfSpecifiedUsers1: [],
id:"",
};
},
methods: {
getServiceCenter(id) {
ServiceCenterService.get(id)
.then((response) => {
this.currentServiceCenter = response.data;
console.log(response.data);
})
.catch((e) => {
console.log(e);
});
},
updateServiceCenter() {
ServiceCenterService.update(this.currentServiceCenter.id, this.currentServiceCenter)
.then((response) => {
console.log(response.data);
this.message = "The service center was updated successfully!";
})
.catch((e) => {
console.log(e);
});
},
deleteServiceCenter() {
ServiceCenterService.delete(this.currentServiceCenter.id)
.then((response) => {
console.log(response.data);
this.$router.push({ name: "service centers" });
})
.catch((e) => {
console.log(e);
});
},
retrieveAllUsersByServiceCenterId(currentServiceCenter){
UsersInServiceCenterService.getAllUsersByServiceCenterId(currentServiceCenter.id)
.then((response) => {
this.listOfSpecificServiceCenter1 = response.data;
console.log(response.data);
})
.catch((e) => {
console.log(e);
});
},
retrieve(){
this.retrieveAllUsersByServiceCenterId(this.currentServiceCenter);
if(this.listOfSpecificServiceCenter1.length!=0){
for(var i =0 ; i<this.listOfSpecificServiceCenter1.length;i++){
UserService.get(this.listOfSpecificServiceCenter1[i].userId)
.then((response) => {
this.listOfSpecifiedUsers1.push(response.data);
console.log(response.data);
})
.catch((e) => {
console.log(e);
});
}
}
this.isEmpty = !this.isEmpty;
},
},
mounted() {
this.message = "";
this.getServiceCenter(this.$route.params.id);
},
};
</script>
getServiceCenter(id) works fine and it returns the service center. However both of the retrieve() and the retrieveAllUsersByServiceCenterId(currentServiceCenter) do not work at all and they return the empty array. Here is the first component which works totally fine with literally the exact same functions.
import UserService from "../services/UserService";
import UsersInServiceCenterService from "../services/UsersInServiceCenterService";
export default {
name: "servicecenters-list",
data() {
return {
serviceCenters: [],
users:[],
currentServiceCenter: null,
currentUser: null,
currentIndex: -1,
currentUserIndex: -1,
id: "",
searchValue: "",
isEmpty: false,
rows: [],
listOfSpecificServiceCenter:[],
listOfSpecifiedUsers:[],
};
},
methods: {
retrieveServiceCenters() {
ServiceCenterService.getAllServiceCenters()
.then((response) => {
this.serviceCenters = response.data;
console.log(response.data);
})
.catch((e) => {
console.log(e);
});
},
retrieveUsers() {
UserService.getAllUsers()
.then((response) => {
this.users = response.data;
console.log(response.data);
})
.catch((e) => {
console.log(e);
});
},
refreshList() {
this.retrieveServiceCenters();
//this.retrieveUsers();
this.currentServiceCenter = null;
this.currentIndex = -1;
//this.currentUser = null;
//this.currentUserIndex = -1;
},
setActiveServiceCenter(servicecenter, index) {
this.currentServiceCenter = servicecenter;
this.currentIndex = index;
},
setActiveUser(user,userIndex){
this.currentUser= user;
this.currentUserIndex = userIndex;
},
// showList(currentServiceCenter){
// for(var i =0;i<currentServiceCenter.users.length;i++){
// }
// },
retrieve(){
this.retrieveAllUsersByServiceCenterId(this.currentServiceCenter);
if(this.listOfSpecificServiceCenter.length!=0){
for(var i =0 ; i<this.listOfSpecificServiceCenter.length;i++){
UserService.get(this.listOfSpecificServiceCenter[i].userId)
.then((response) => {
this.listOfSpecifiedUsers.push(response.data);
console.log(response.data);
})
.catch((e) => {
console.log(e);
});
}
}
this.isEmpty = !this.isEmpty;
},
retrieveAllUsersByServiceCenterId(currentServiceCenter){
UsersInServiceCenterService.getAllUsersByServiceCenterId(currentServiceCenter.id)
.then((response) => {
this.listOfSpecificServiceCenter = response.data;
console.log(response.data);
})
.catch((e) => {
console.log(e);
});
},
addUserToServiceCenter(currentServiceCenter, currentUser) {
var data = {
serviceCenterId: parseInt(this.currentServiceCenter.id),
userId: parseInt(this.currentUser.id),
};
UsersInServiceCenterService.add(data)
.then((response) => {
//this.currentServiceCenter.id = response.data.id; //take care here
console.log(response.data);
this.submitted = true;
})
.catch((e) => {
console.log(e);
});
this.show=false
if(currentServiceCenter.users == Array.isArray(currentServiceCenter.users))
//currentServiceCenter.users = Array.isArray(currentServiceCenters.users) : [...currentServiceCenter.users, currentUser] : [currentUser]
currentServiceCenter.users.push(currentUser);
else{
currentServiceCenter.users = []
currentServiceCenter.users.push(currentUser);
}
},
removeAllServiceCenters() {
ServiceCenterService.deleteAllServiceCenters()
.then((response) => {
console.log(response.data);
this.refreshList();
})
.catch((e) => {
console.log(e);
});
},
searchId(id) {
ServiceCenterService.get(id)
.then((response) => {
this.currentServiceCenter = response.data;
})
.catch((e) => {
console.log(e);
});
this.refreshList();
// if(typeof id ==='string'){
// }
// else if(typeof id==='number'){
// CompanyService.get(id).then(response =>{
// this.currentCompany=response.data
// })
// .catch(e=>{
// console.log(e);
// });
// }
},
},
mounted() {
this.retrieveServiceCenters();
this.retrieveUsers();
},
computed:{
usersFilteredListByName(){
if(this.searchValue.trim().length >0){
return this.serviceCenters.filter((servicecenter) =>servicecenter.name.toLowerCase().includes(this.searchValue.trim()))
}
// if(this.searchValue.length>0 && isNaN(parseInt(this.searchValue))){
// return this.companies.filter((company) =>company.id.includes(this.searchValue))
// }
return this.serviceCenters
},
usersFilteredListById(){
if(this.searchValue.trim().length >0){
return this.serviceCenters.filter((servicecenter) =>servicecenter.id.toString().includes(this.searchValue))
}
return this.serviceCenters
},
}
};
</script>
You can ignore the rest of the functions and focus on the retrieve() and retrieveAllUsersByServiceCenterId(). Any help would be highly appreciated.

Loaded fields are not initialized in the additional function

I use two functions to load some components for my page and save it in two fields representatives and allUsers. Then I try to use additional func subtractSets() to a little bit modify loaded data. My problem is that fields this.representatives and this.allUsers in this adittional function are still not initialized. What I can do to get loaded data in subtractSets()?
setup() {
const representatives = ref([])
const allUsers = ref([])
data() {
return {
representatives,
users
}
}
},
methods(): {
loadUsersRepresentatives() {
axios.get('getRepresentatives').then(res => {
this.representatives = res.data
}).catch(() => {
...
})
});
},
loadAllUsers() {
axios.get('/getAllUsers').then(res => {
this.allUsers = res.data
}).catch(() => {
...
})
});
},
subtractSets(obj1, obj2) {
...
},
showRepresentativesDialog(facultyID) {
this.loadUsersRepresentatives(facultyID)
this.loadAllUsers()
this.subtractSets(this.representatives, this.allUsers)
this.representativesDialog = true
}
},
ยดยดยด
You are missing async / await
methods(): {
async loadUsersRepresentatives() {
return axios.get('getRepresentatives').then(res => {
this.representatives = res.data
}).catch(() => {
...
})
});
},
async loadAllUsers() {
return axios.get('/getAllUsers').then(res => {
this.allUsers = res.data
}).catch(() => {
...
})
});
},
subtractSets(obj1, obj2) {
...
},
async showRepresentativesDialog(facultyID) {
await this.loadUsersRepresentatives(facultyID)
await this.loadAllUsers()
this.subtractSets(this.representatives, this.allUsers)
this.representativesDialog = true
}
},

how to clear setTimeOut when component unmounts

i try to get Items data. if request response less than 1 i have to request again. so i write a recursive function with setTimeout. but when i try to change my route function keeps working. window.clearTimeout() or global.clearTimeOut() not worked here when component unmounts. Do i miss something?
useEffect(() => {
getItems(params);
return () => {
window.clearTimeout();
global.clearTimeout();
}
}, []);
const getItems = async(params) => {
try {
const { data = []} = await axios.get('/some-endpoint',params);
dispatch({ type: ITEMS_START });
if (data.length === 0) {
setTimeout(() => {
getItems(params);
}, 5000);
} else {
dispatch({ type: ITEMS_SUCCESS, payload: { data } });
}
} catch (error) {
dispatch({ type: ITEMS_ERROR, payload: error });
}
}
Use a ref to store the timeout ID and then clear that timeout.
const timeoutRef = React.useRef();
useEffect(() => {
getItems(params);
return () => {
window.clearTimeout(timeoutRef.current);
}
}, []);
const getItems = async(params) => {
try {
const { data = []} = await axios.get('/some-endpoint',params);
dispatch({ type: ITEMS_START });
if (data.length === 0) {
timeoutRef.current = setTimeout(() => {
getItems(params);
}, 5000);
} else {
dispatch({ type: ITEMS_SUCCESS, payload: { data } });
}
} catch (error) {
dispatch({ type: ITEMS_ERROR, payload: error });
}
}
Create a reference you can set your timeout too that the unmount can call back to.
let timeout = null;
useEffect(() => {
getItems();
return () => {
if(timeout)
clearTimeOut(timeout)
}
})
const getItems = () => {
timeout = setTimeOut(() => work, 5000);
}
This is the general idea.
Each SetTimeout ( and setInterval ) returns a number which can be used to clear it. ie, var x = setTimeout(() => console.log('timeout'),1000); clearTimeout(x); will do nothing.

With React, how can I reuse the setState function instead of copying and pasting?

I have an app I'm making. The idea is that you set the state to different things based off what you click. In this case, the state is the image src variable. I currently have this...
merryWeather = () => {
this.setState({
imgPath: merrys
})
}
maxJPegasus = () => {
this.setState({
imgPath: pega
})
}
betterCallLamar = () => {
this.setState({
imgPath: lamars
})
}
betterCallLester = () => {
this.setState({
imgPath: lesters
})
}
And some other state setting functions. How can I write these as one function, and call that same function over and over?
Create a single function and pass the parameter to be set as imgPath.
setImgPath = (imgPath) => {
this.setState({imgPath});
}
You can create an updateState function that accepts a name and value or a function that updates imgPath for you.
updateState = (name, value) => {
this.setState({
[name]: value
});
}
merryWeahter = () => {
this.updateState('imgPath', merrys);
}
maxJPegasus = () => {
this.updateState('imgPath', pega);
}
OR
updateImgPath = value => {
this.setState({
imgPath: value
});
}
merryWeahter = () => {
this.updateImgPath(merrys);
}
maxJPegasus = () => {
this.updateImgPath(pega);
}

How to check meteor.call method ran successfully?

I am using meteor/react. I have two components. I want to pass method from one:
saveNewUsername(newUsername) {
Meteor.call('setNewUsername', newUsername, (error) => {
if(error) {
Materialize.toast(error.reason, 4000);
} else {
Materialize.toast('Username changed!', 4000);
}
});
}
And than I need to check it for success:
handleSaveOption() {
const { howToChangeOption } = this.props;
const optionValue = this.option.value.trim();
if(howToChangeOption(optionValue)) {
this.setState((prevState) => ({
startToChange: !prevState.startToChange,
}));
}
}
So, how to check Meteor.call for success and return true or false? Thanks!
Solved with promises. Maybe anyone has better solution?
saveNewUsername(newUsername) {
return new Promise((resolve, reject) => {
Meteor.call('setNewUsername', newUsername, (error) => {
if(error) {
Materialize.toast(error.reason, 4000);
reject();
} else {
Materialize.toast('Username changed!', 4000);
resolve();
}
});
});
}
handleSaveOption() {
const { howToChangeOption } = this.props;
const optionValue = this.option.value.trim();
howToChangeOption(optionValue).then(() => {
this.setState((prevState) => ({
startToChange: !prevState.startToChange,
}));
});
}

Categories

Resources