setinterval function is running infinitely - react-native

const interval = setInterval(() => {
fire.database().ref().child(getpath())
.once("value",
(snapshot) => {
let item = snapshot.val()
console.log(item)
if (item !== null) {
let array = [];
Object.
keys(item)
.forEach(i => array.push(item[i]));
setCard1(array);
}
console.log(item, "item")
if (item !== null) {
itemlen = 7 //length of object I get from valid result
//stop polling for results
console.log(itemlen, "should clear")
}
else {
console.log("polling")
}
})
}, 1000)
console.log("comingout")
if (itemlen !== 0) {
console.log("goingIn")
clearInterval(interval);
}
}, [prefVar]);
expected clearinterval to stop the setinterval function but it is running continuosly and not stopping
itemlen is getting non zero values.Is there a better way of implementing this ?
I want stop useEffect once I get valid value from db.My code inside the for setinterval selects a random path and retrieve that path only problem is that sometimes the path is empty,thus using setInterval

I would create two state items, one which keeps the interval and the other which stores itemlen, and would use another useEffect to listen on changes to itemlen, and when it is not 0, the interval should clear. Also, I would check if there is another interval running before you start another one.
const [itemlen, setItemlen] = useState(0);
const [pollingInterval, setPollingInterval] = useState(null);
useEffect(() => {
if (pollingInterval === null) {
setPollingInterval(setInterval(() => {
fire.database().ref().child(getpath())
.once("value",
(snapshot) => {
let item = snapshot.val()
console.log(item)
if (item !== null) {
let array = [];
Object.
keys(item)
.forEach(i => array.push(item[i]));
setCard1(array);
}
console.log(item, "item")
if (item !== null) {
setItemlen(7);
console.log("should clear")
} else {
console.log("polling")
}
})
}, 1000));
}
}, [prefVar]);
useEffect(() => {
if (itemlen !== 0 && pollingInterval !== null) {
clearInterval(pollingInterval);
setPollingInterval(null);
}
}, [itemlen])

Related

ProtocolError: Protocol error (Runtime.callFunctionOn): Target closed. - express.js and puppeteer-cluster

I want to iterate over key-pairs of data.extractRules and get elements data from the page.
This snippet inside forEach loop is causing app crashes. I tried hardcoding key and cssSelector and tried this outside of forEach loop and it worked.
const extractContent = {};
if (data.extractRules !== null) {
Object.entries(data.extractRules).forEach(async ([key, cssSelector]) => {
extractContent[key] = await page.$$eval(cssSelector, (elements) =>
elements.map((element) => element.outerHTML)
);
});
}
I figured out solution 😁
async function getSelectorContent(page, cssSelector) {
return page.$$eval(cssSelector, (elements) =>
elements.map((element) => element.outerHTML)
);
}
const extractContent = {};
if (data.extractRules !== null) {
await Object.entries(data.extractRules).reduce(
async (item, [key, cssSelector]) => {
await item;
extractContent[key] = await getSelectorContent(page, cssSelector);
},
Promise.resolve()
);
}

Issue with react-native FlatList rendering data when updating array of objects maintained in redux

I'm loading a dynamic form in a FlatList. I'm supposed to add few rows with UI elements such as TextInput, checkbox, etc. based on a condition. For example, I have a dropdown, when I select a value, I have to add a row with a button and remove that row when I select another value.
My issue is that whenever I select a value in the dropdown to add a row with button, FlatList is adding duplicate rows and they are not visible as objects in my array when I debug them. I'm using Redux to manage my application state and updating my array in reducers.
I have to display objects in my array in FlatList without any duplicates using Redux for state management.
Code:
<FlatList
key={Math.floor(Math.random())}
ref={(ref) => { this.flatListRef = ref; }}
data={this.state.mainArray}
renderItem={this._renderItem}
keyExtractor={({ item, id }) => String(id)}
extraData={this.prop}
keyboardDismissMode="on-drag"
showsVerticalScrollIndicator={false}
scrollEnabled={true}
removeClippedSubviews={false}
scrollsToTop={false}
initialNumToRender={100}
/>
componentWillReceiveProps(nextProps) {
this.setState({mainArray: nextProps.mainArray});
}
Updating array in Reducer:
case VALIDATE_DEPENDENCY: {
// adding or removing dependency questions
let dependingQues = [];
let formArrayTemp = [...state.mainArray];
let exists;
// console.log("formArrayTemp123", formArrayTemp);
if (action.item.isDependentQuestion) {
if (action.item.dependentQuestionsArray.length > 0) {
let dependent_ques = action.item.dependentQuestionsArray[0];
state.depending_questions_array.filter((obj, id) => {
if (JSON.stringify(obj.key_array) === JSON.stringify(dependent_ques.key)) {
dependingQues.push(obj);
}
});
// console.log("dependingQues123", dependingQues);
if (dependent_ques.answer === action.item.answer) {
dependingQues.map((obj, id) => {
exists = formArrayTemp.filter((res, idx) => {
if (JSON.stringify(res.key_array) === JSON.stringify(obj.key_array)) {
return res;
}
});
// console.log("exists123", exists);
if (exists.length === 0) {
formArrayTemp.splice(action.index + id + 1, 0, obj);
// console.log("mjkgthbythyhy", action.index + id + 1);
}
});
}
else {
let objIndex = formArrayTemp.findIndex(obj => JSON.stringify(obj.key_array) === JSON.stringify(dependent_ques.key));
if (objIndex !== -1) {
formArrayTemp[objIndex].answer = "";
formArrayTemp[objIndex].borderColor = "black";
formArrayTemp.splice(objIndex, 1);
// console.log("frtg6hyjukiu", formArrayTemp);
}
}
}
}
// adding or removing dependent sections
let dependentSections = [];
let tempArr = [];
let count = 0;
if (action.item.isDependent) {
if (action.item.dependentArray.length > 0) {
let dependent_section = action.item.dependentArray[0];
state.dependent_sections_array.filter((obj, id) => {
if (obj.section_id === dependent_section.section_id) {
dependentSections.push(obj);
}
});
// console.log("dependentSections123", dependentSections);
let lastIndex;
formArrayTemp.filter((res, id) => {
if (action.item.section_id === res.section_id && res.dependentArray &&
JSON.stringify(action.item.dependentArray) === JSON.stringify(res.dependentArray)) {
tempArr.push(res);
lastIndex = formArrayTemp.FindLastIndex(a => a.section_id === res.section_id);
}
});
// console.log("lastIndex123", lastIndex);
tempArr.map((obj, id) => {
if (obj.answer === obj.dependentArray[0].answer) {
count++;
}
});
if (dependent_section.answer === action.item.answer) {
dependentSections.map((obj, id) => {
if (formArrayTemp.contains(obj) === false) {
formArrayTemp.splice(lastIndex + id + 1, 0, obj);
// console.log("cfrererfre", formArrayTemp);
}
});
}
else {
let countTemp = [];
if (count === 0) {
let countTemp = [];
dependentSections.filter((res, id) => {
if (formArrayTemp.contains(res) === true) {
formArrayTemp.filter((obj, idx) => {
if (obj.section_id === res.section_id) {
obj.answer = "";
obj.borderColor = "black";
countTemp.push(obj);
}
});
}
});
let jobsUnique = Array.from(new Set(countTemp));
formArrayTemp = formArrayTemp.filter(item => !jobsUnique.includes(item));
// console.log("frefrefre123", formArrayTemp);
// return { ...state, mainArray: [...formArrayTemp] }
}
}
}
}
console.log("formArray123", formArrayTemp);
formArrayTemp.sort((a, b) => {
return a.posiiton - b.position;
});
return { ...state, mainArray: formArrayTemp }
};
Update
After researching this issue I came across this issue #24206 in GitHub. There it states:
There's a few things you aren't doing quite correctly here. Each time the render function runs you are creating a new array object for your data, so React has to rerender the entire list each time, you're renderItem function and keyExtractor function are also remade each rerender, and so the FlatList has to be rerun. You're also using the index for your key which means as soon as anything moves it will rerender everything after that point. I would recommend looking at what does/doesn't change when you rerun things (arrays, functions, object), and why the keyExtractor is important for reducing re-renders.
So I tried commenting KeyExtractor prop of FlatList and the issue got resolved. But this is causing issue in another form. How can I resolve that?

Vue.js - Element UI - get the state of form validation

Steps to reproduce
The recurrence link is this: https://stackblitz.com/edit/typescript-vuejs-element-3kko7a
password input 2
username input 11
Change username to 2// should be able to submit, but not
Expected: formvalid = true
Validate Code here:
checkForm() {
// console.log('validate runs');
// #ts-ignore
const fields = this.$refs.ruleForm.fields;
if (fields.find((f) => f.validateState === 'validating')) {
setTimeout(() => {
this.checkForm();
}, 100);
}
this.formValid = fields.reduce((acc, f) => {
const valid = (f.isRequired && f.validateState === 'success');
const notErroring = (!f.isRequired && f.validateState !== 'error');
return acc && (valid || notErroring);
}, true);
console.log('valid:', this.$data.formValid);
}
Basically you watch ruleForm - so everytime ruleForm changes you trigger checkform - but your validtor triggers on blur after you set ruleForm so you first test then turn valid. change this into a getter:
get formValid(){
const fields = this.$refs.ruleForm.fields || [];
if (fields.find((f) => f.validateState === 'validating')) {
setTimeout(() => {
this.checkForm();
}, 100);
}
return fields.reduce((acc, f) => {
const valid = (f.isRequired && f.validateState === 'success');
const notErroring = (!f.isRequired && f.validateState !== 'error');
return acc && (valid || notErroring);
}, fields.length > 0);
}

react-native-numeric-input change event is not triggered

I'm currently working on a react project using multiple libraries including react-native-numeric-input which for some reason have a lot of unexpected behaviours.
Last night I had everything working as it should be but when I can to take another look the numeric input + and - buttons are not responding to any of the clicks, I even added a console.log to the onChange prop to test if the value is not changing or the event is not triggered and i didn't get anything.
this the numeric input:
<NumericInput
onChange={num => {
console.log(num);
this.setState({ updateItem: num}, this.saveChangedConfigs);
console.log('input', this.state);
}}
value={this.state.updateItem}
totalWidth={configValues.inw}
totalHeight={configValues.inh}
initValue={this.state.updateItem}
inputStyle={{ backgroundColor: '#f4f4f4'}}
containerStyle={styles.updateValue}
minValue={1}
/>
these are the two methods that change the state:
saveChangedConfigs = async () => {
try {
this.props.saveConfigs({
stockpile: this.state.updateItem.toString(),
data: this.state.updateData.toString(),
delete: this.state.emptyFiles.toString(),
autoUpdate: this.state.autoUpdate.toString(),
language: this.state.language
})
await this.initConfigs();
} catch (error) {
console.log('save err', error);
}
}
and
initConfigs = async () => {
const configs = await AsyncStorage.multiGet([
'updateStockpile',
'updateData',
'emptyPhone',
'language',
'autoUpdate'
])
console.log("configs", configs)
const confs = {
stockpile: this.props.config.stockpile,
autoUpdate: this.props.config.autoUpdate,
language: this.props.config.language,
data: this.props.config.data,
delete: this.props.config.delete
}
await configs.map(conf => {
switch(conf[0]){
case 'updateStockpile': if(conf[1] !== null) confs.stockpile = conf[1]; break;
case 'updateData': if(conf[1] !== null) confs.data = conf[1]; break;
case 'emptyPhone': if(conf[1] !== null) confs.delete = conf[1]; break;
case 'language': if(conf[1] !== null) confs.language = conf[1]; break;
case 'autoUpdate': if(conf[1] !== null) confs.autoUpdate = conf[1]; break;
}
})
await this.props.initConfigs(confs);
await this.setState({
language: confs.language,
updateItem: Number(confs.stockpile),
updateData: Number(confs.data),
emptyFiles: Number(confs.delete),
autoUpdate: confs.autoUpdate
});
}
this is my initial state:
this.state = {
language: this.props.config.language,
updateItem: Number(this.props.config.stockpile),
updateData: Number(this.props.config.data),
emptyFiles: Number(this.props.config.delete),
autoUpdate: this.props.config.autoUpdate
}
Hope you guys can help me out with this or maybe suggest an alternative if you know about one.

Behavior Subject unsubscribe refactor

This can't be the only way to unsub Behavior Subjects :
maxSub;
fromSub;
toSub;
pageNumberSub;
originalMaxSub;
selectionSub;
selectionOfInterestSub;
constructor(private store: StoreService) {}
ngAfterContentChecked(){
this.maxSub = this.store.max$.subscribe((max) => {
if(max !== null && max !== undefined){
this.max = max;
this.maxPages = Math.floor(this.max / Variables.to);
this.pages = Array.from(Array(this.maxPages), (x, i) => i + 1);
}
}, (error) => console.log(error), () => {});
this.fromSub = this.store.from$.subscribe((from) => {
if(from !== null && from !== undefined) {this.from = from; this.split = this.to - (this.from - 1)}
}, (error) => console.log(error), () => {});
this.toSub = this.store.to$.subscribe((to) => {
if(to !== null && to !== undefined) {this.to = to; this.split = this.to - (this.from - 1)}
}, (error) => console.log(error), () => {});
this.pageNumberSub = this.store.pageNumber$.subscribe((pageNumber) => {
if(pageNumber !== null && pageNumber !== undefined) {this.page = pageNumber;}
}, (error) => console.log(error), () => {});
this.originalMaxSub = this.store.originalMax$.subscribe((originalMax) => {
if(originalMax !== null && originalMax !== undefined) {this.originalMax = originalMax;}
}, (error) => console.log(error), () => {});
this.selectionSub = this.store.selection$.subscribe((selection) => {
if(selection !== null && selection !== undefined) this.selectedAmount = selection.length;
}, (error) => console.log(error), () => {});
this.selectionOfInterestSub = this.store.selectionOfInterest$.subscribe((selectionOfInterest) => {
if(selectionOfInterest !== null && selectionOfInterest !== undefined) this.selectionOfInterest = selectionOfInterest;
}, (error) => console.log(error), () => {});
}
ngOnDestroy(){
this.maxSub.unsubscribe();
this.fromSub.unsubscribe();
this.toSub.unsubscribe();
this.pageNumberSub.unsubscribe();
this.originalMaxSub.unsubscribe();
this.selectionSub.unsubscribe();
this.selectionOfInterestSub.unsubscribe();
}
in regular old Observables you can just :
alive = true;
constructor(private store: StoreService) {}
ngAfterContentChecked(){
this.store.thing.subscribe().takeWhile(this.alive)...
}
ngOnDestroy(){
this.alive = false;
}
which is much simpler.
Isn't there a way to do the same with Behavior Subjects?
Another thing : am I missing a fundamental property of Behavior Subjects that they only subscribe once within an class no matter how many times the subscribe is called and that's why there's no such thing as takeWhile() on Behavior Subjects?
1 - Actually what you call it a simpler way does not unsubscribe at all it just stop reading what comes from the observable. So either use unsubscribe or complete.
2 - Since you are unsubscribing at the same time and you clearluy don't use the Subject for anything else, then it's fine to use the same Subject variable for all your subs and then you can unsubscribe with oneline of code and you don't need to initialize all these Subject instances.