Looking to add some items, display a list then be able to delete each item separately, my understanding of this problem is that I have to create an array then update it each time I want to delete an item then save. That seems quite complex for a basic db operation, I tried several approachs don't know if my code is what I'm supposed to do. Can someone please point to the right direction?
The last error I'm facing:
Object is null or undefined from
C:\Users\oled\stock\node_modules\react-native\Libraries\polyfills\Array.es6.js:24:26
_toConsumableArray
FetchValue = () => {
AsyncStorage.getItem("Favorites").then((value) => {
this.setState({
favs: JSON.parse(value)
});
}).done();
};
SaveValue = () => {
const newFavs = [...this.state.favs, this.state.UserInput];
this.setState({ favs: newFavs, UserInput: '' }, () => {
AsyncStorage.setItem("Favorites", JSON.stringify(this.state.favs));
Keyboard.dismiss()
});
};
RemoveValue(item){
const index = this.state.favs.indexOf(item);
const newArray = [...this.state.favs];
newArray.splice(index,1);
this.setState({ favs: newArray });
AsyncStorage.setItem("Favorites", JSON.stringify(newArray));
}
Full code : https://pastebin.com/p7sbQTNG
I think after removing last element, your array is empty. So after that whenever you try to remove the value from array it will give you the error. So please check the condition where array count is greater than 0 or not.
I hope it will work for you.
replace your RemoveValue method with this code.
We need to check if the item is not null/undefined
RemoveValue(item){
if(item !== null && item !== undefined){
const index = this.state.favs.indexOf(item);
const newArray = [...this.state.favs];
newArray.splice(index,1);
this.setState({ favs: newArray });
AsyncStorage.setItem("Favorites", JSON.stringify(newArray));
}
this will resolve your crash.
Related
In app.jsn i got an increment function, which should increase listVoca, a list of object thus {word:'word', translation: 'translation', count:0}
incrementVoca = indexToIncrement => {
this.setState(prevState => {
let listVoca = [...prevState.listVoca];
let vocaToIncrement = listVoca[indexToIncrement];
vocaToIncrement['point']++;
listVoca[indexToIncrement] = vocaToIncrement;
return {listVoca};
},() => {
AsyncStorage.setItem('listVoca', JSON.stringify(this.state.listVoca));
});
}
I call it with the increment function by pressing a button :
{increment=()=>{
this.props.screenProps.incrementVoca(this.state.index)
this.takeRandomVoca();
}
However, the count is not incremented, and this.takeRandomVoca() is not called. Can please someone explaine me why ?
im having this error every time i type even one letter in my search bar and i dont know how to fix. sorry noob dev
const [dataList] = useState(data)
const [filtered, setFiltered] = useState(dataList);
const onSearch = (text) => {
if (text) {
const temp = text.toLowerCase();
const tempList = dataList.filter(item => {
if (item.match(temp))
return item
})
setFiltered(tempList);
setSearching(true);
}
else {
setFiltered(dataList);
setSearching(false);
}
};
here is the error i get
hi maybe item is not a String, it needs to be.
and another syntax advice.
change to return item.match(temp)
I am using Quasar Framework and using the Q-Select with filter.
I would like to the first filtered option always be already marked, because then if I hit enter, the first will selected.
After some research I found out how to achieve this in a generic way.
The second parameter on the function update received at filterFn is the instance of QSelect itself.
Hence, we can use
ref.setOptionIndex(-1);
ref.moveOptionSelection(1, true);
To keep the focus on the first filtered element, regardless of multiselect or not.
The final code is something like
filterFn(val, update) {
update(
() => {
const needle = val.toLocaleLowerCase();
this.selectOptions = this.qSelectOptions.filter(v => v.toLocaleLowerCase().indexOf(needle) > -1);
},
ref => {
ref.setOptionIndex(-1);
ref.moveOptionSelection(1, true);
});
}
There is one option to achieve this is set model value in the filter method if filtered options length is >0.
filterFn (val, update, abort) {
update(() => {
const needle = val.toLowerCase()
this.options = stringOptions.filter(v => v.toLowerCase().indexOf(needle) > -1)
if(this.options.length>0 && this.model!=''){
this.model = this.options[0];
}
})
}
Codepen - https://codepen.io/Pratik__007/pen/QWjYoNo
how to get variable from outer layer method
trying to use a variable in outer layer in my React-Native App
updateCheckBox() {
Constants.TABS.map((item) => {//Constants.TABS is an array
AsyncStorage.getItem(item)//using item as key to fetch from AsyncStorage
.then((res) => {
if(res == 1) {
//debugged here, item was undeined. but i need setState here with item as key. How should i get item here.
this.setState({item: true}) // I need to get the item here, but it show undefined
} else {
this.setState({item:false}) // I need to get the item here, but it show undefined
}
})
})
}
// I need to get the item here, but it show undefined
You need to wrap the item in [] to use it as a key for a property. Like this:
updateCheckBox() {
Constants.TABS.map(item => {
AsyncStorage.getItem(key) //
.then((res) => {
//item is accessible here, to use item as the key to a property wrap it in []
if(res == 1) {
this.setState({[item]: true});
} else {
this.setState({[item]: false});
}
})
})
}
finally, I found there is no issue in this code, the thing is
updateCheckBox() {
Constants.TABS.map((item) => {
let key = item
AsyncStorage.getItem(key)
.then((res) => {
console.log(item, "item is here", res); //item is visible here
console.log(key) //key is all always undefined
if(res == 1) {
this.setState({item: true})
} else {
this.setState({item:false})
}
})
})
}
key is not visible in method then, which I can not explain, but all in all, my code works.
I followed the example from official docs, here is how to implement multiselection feature:
state = { selected: (new Map(): Map<string, boolean>) };
onPressItem = (id) => {
this.setState((state) => {
const selected = new Map(state.selected);
selected.set(id, !selected.get(id));
return { selected };
});
};
I'm struggling with making it single select though. It's easy to return new Map with false values anytime cell is tapped, but that means the cell cannot be deselected by another tap on it, which is the desired feature in my case.
onPressItem = (id) => {
this.setState((state) => {
const selected = new Map();
selected.set(id, !selected.get(id));
return { selected };
});
};
How would you implement it? Should I use lodash to iterate over the Map to find the one that already is true and change its value (now sure how to iterate over Map though), or maybe there is some better approach I am missing right now?
EDIT
Iterating over elements of the selected Map seems to be a really ugly idea, but it is simple and it actually works. Is there any better way to do it that I am missing out on?
onPressItem = (id: string) => {
this.setState((state) => {
const selected = new Map(state.selected);
selected.set(id, !selected.get(id));
for (const key of selected.keys()) {
if (key !== id) {
selected.set(key, false);
}
}
return { selected };
});
};
Thanks in advance
You can just set only one value instead of a map like this
onPressItem = (id) => {
this.setState((state) => {
const selected = selected === id ? null : id;
return { selected };
});
};
I had the same issue, my solution was:
_onPressItem = (id: string) => {
// updater functions are preferred for transactional updates
this.setState((state) => {
// copy the map rather than modifying state.
const selected = new Map(state.selected);
// save selected value
let isSelected = selected.get(id);
// reset all to false
selected.forEach((value, key) => {
selected.set(key, false);
});
// then only activate the selected
selected.set(id, !isSelected);
return { selected };
});
};