setState is not updating the state, even in its callback react-native - javascript

here the user_res is updated but not the state, and I have tried binding this function to this also. but same result :(
let user_res = usr_vote;
user_res.map((vote)=>{
if(vote.id==dat_id){
vote.status = stats
}
})
console.log("update user response:",user_res)
this.setState({user_response:user_res},()=>{
console.log("but this is not uodating : ",this.state.user_response)
});

I don't think even user_res is updating. map doesn't update the original variable. You need to assign the value of .map to something.
user_res = user_res.map((vote)=>{
if(vote.id==dat_id){
return {...vote, status: stats}
} else {return vote}
})

If you check documentation form Array.prototype.map(), you will see that map doesn't modify the original array, it returns a new array with the modified items.
The map() method creates a new array with the results of calling a
provided function on every element in the calling array.
So with that information you can modify your code accordingly,
// create a new array with the modified items
let user_res = usr_vote.map((vote) => {
if(vote.id == dat_id){
vote.status = stats
}
});
// update state with the new array
this.setState({user_response:user_res},()=>{
console.log("but this is not uodating : ",this.state.user_response)
});
PS: stats is not defined anywhere in your snippet. If you are not defining it somewhere in your code that your shared snippet doesn't contain, it is OK but otherwise you need to fix that part too.

Related

When pushing a new value inside an array it gets totally override - VUEX

Hello so I am creating a filter search and I 'm trying to collect all the key (tags) that the user press, inside an array, however every time that a new value is push it does override the entire array. So I tried a couple of things, like spread syntax, concat, etc. But with no luck.
So my action looks like this:
const setCurrentFilters = async (context, payload) => {
if (payload) {
context.commit('setCurrentFilter');
}
}
My state
state:{
filters: JSON.parse(sessionStorage.getItem('currentFilters') || '[]'),
}
The mutation
setCurrentFilter(state, payload) {
state.filters.push(payload);
sessionStorage.setItem('currentFilters', JSON.stringify(payload));
}
And my getter
currentFilters(state) {
return state.filters;
},
Thank you in advance for any help : )
This is simply because you set const filters = []; which means that the next condition if (filters.length) will always return false (as you just created this array) and therefore the else statement will execute.
in the else statement you basically push the new payload to the empty array you just initialized - which makes your array always hold only the new value
i believe that you just need to remove the const filters = []; line, and access the filters property that exists in your state

Global array not updating when I call a Firebase function

I have a few lines of code which retrieve data from a Firebase realtime database. I want them to grab a name from objects stored there and then use this to pick a random name. do this by first retrieving all objects and storing the name values in an array. I then retrieve the number of total objects in that database and use the random function to generate a random number, and then pick that value from the array. I am not sure why this is not behaving as it should. Here is the code I am using:
const dbRefObject = firebase.database().ref().child('names');
dbRefObject.on('value', gotData);
var names = [];
function gotData(data) {
dbRefObject.once('value', function (snapshot) {
snapshot.forEach(function (childSnapshot) {
var childData = childSnapshot.val().names;
names.push(childData);
})
namesUpdated(names);
}
)
return names;
}
function namesUpdated(names) {
randomNumber = randomNumberGenerator();
console.log(randomNumber);
console.log(names[randomNumber]);
return names[randomNumber];
}
function randomNumberGenerator() {
dbRefObject.on('value', (snap) => {
var totalRecord = snap.numChildren();
return Math.floor(Math.random() * totalRecord);
});
}
I am not sure why this is not working as when I print out the names array in gotData function it works fine. However when I try to use this in namesUpdated it says the value is undefined. Similarly, the randomNumberGenerator works fine as it returns a value in that function but does not work when I use it in namesUpdated. That function looks fine to me so I am not sure why it isnt working. Thanks in advance for any help.
There are several problems in your code. I'll try to identify the main ones and I would suggest you update your question with a new version.
First, IMHO, you should move the declaration of the names array IN the gotData() function:
function gotData(data) {
var names = [];
Secondly, in the randomNumberGenerator() function you should use once() instead of on(). You should also do return dbRefObject.once('value', (snap) => {...}).
Then, in namesUpdated(), you should note that the call to randomNumberGenerator() returns a Promise, therefore you cannot do var randomNumber = randomNumberGenerator();. You should either use then() or use async/await.
Finally, by separating your code in different functions, you are fetching the database several times, without any added value.

Filter an Object Array and set to state Array variable

This is the JSON Input that I am going to filter by orderId and then set to the state variable.
[{"orderId":3,"userId":3,"firstName":"Amal","lastName":"kankanige","contactNo":"011-3456787","status":"pending","deliveryAddress":"No:24/c,Anders Road,Wijerama,Wijerama,Srilanka","productName":"Apple","quantity":2,"total":100.0,"id":null,"order_date":"2019-01-31 10:28:29"}]
this is my state.
this.state = {
merchentOrders: [],
filterMerchentOrders: []
}
//this is the method
when I am filtering by orderId it's successfully working and then I want to set the filtered output to " this.setState({filterMerchentOrders: filterMerchentOrdersX});". when I console out the state as below the values are not set.
getOrderDetails = id => {
console.log("id ==" ,id);
let filterMerchentOrdersX = this.state.merchentOrders.filter(value => {
return (
value.orderId.toString()
.indexOf(id) !== -1
);
});
this.setState({filterMerchentOrders: filterMerchentOrdersX});
//this is working
console.log("filterMerchentOrdersX ==" ,filterMerchentOrdersX);
//this gives an empty array
console.log("this.state.filterMerchentOrders ==" ,this.state.filterMerchentOrders);
};
It might be the reason that setState runs asynchronusly, when you console.log the value state might not be updated.
To view the state after it updates, you can pass a callback function.
this.setState({filterMerchentOrders: filterMerchentOrdersX},()=>{
console.log("this.state.filterMerchentOrders ==" ,this.state.filterMerchentOrders);
})
you've written console.log() immediately after setState method, since setState is an async method an at the time java script runs your console.log it will be showing you the previous state in which obviously array is not set, for this you should put your console in the second argument of setState that is a callback function.
this.setState({[event.target.name]: event.target.files[0]},()=>console.log(this.state));
or you can simply user async await.
Since you're using the ES6 syntax, your function could be shorter and neater. But it seems to me that you're not doing anything wrong
getOrderDetails = id => {
const filterMerchentOrders = this.state.merchentOrders.filter(
value => value.orderId.toString().indexOf(id) !== -1
);
this.setState({filterMerchentOrders});
}

Callback function to store values in a Map in ES6

This question might have been asked before but I couldnt find answer after sufficiently searching for one.
I am working on a React app and I need to store the state which is a map in a local variable.
Following is my code which takes the component state and stores it in blockMap:
let blockMap = this.state.editorState.getCurrentContent().getBlockMap();
Then I declare a new Map:
let tempMap = new Map();
Now, I need to store values into the tempMap. So I do something like this:
blockMap.forEach((k,v) => tempMap.set(k,v));
And then I just print out the tempMap to see the set variables. Unfortunately, I get an empty map again. I just dont understand why this is happening. Can someone explain to me if its an ES6 issue or something else?
Following is the full function:
printMapOfEditorState(){
let blockMap = this.state.editorState.getCurrentContent().getBlockMap();
let map = this.state.map;
let tempMap = new Map();
blockMap.forEach((k,v) => tempMap.set(k,v));
console.log(tempMap);
}
Just one more follow up, in the same function I change the map state by using setState like this:
blockMap.forEach(k => {
if(k.getText().replace(/^\s+|\s+$/g, '') !== undefined) {
this.setState({
map: map.set(k.getText(), k.getDepth())
});
}
});
And surprisingly this works. I cant understand this anomolous behaviour. Thanks for help.
The arguments to the callback to forEach take the form of (value, key) as opposed to (key, value), so your forEach should look like
blockMap.forEach((v,k) => tempMap.set(k,v));
^^^ swapped
But you actually don't need a forEach since Map can take another map in the constructor:
let tempMap = new Map(blockMap);

angularjs using .map is not a function

Trying to manipulate the response.data to add isLoggedin = true in the response using .map but its giving me an error of "map" is not a function.
vm.dataResponse = response.data.map(function(data){
data.isLoggedIn = false;
});
Trying to do this so I can have a data to reference whether the user is logged in or not to show (login/sign out). Or I could use $rootScopebut I thought using global is not ideal?
$rootScope.isLoggedIn = false;
then in my vm.login function the $rootScope will then be set to true, this works but when I refresh the page it goes back to false.
response.data will need to be an array in order to use .map
.map will create a new array by iterating through all the values of an existing array and returning the results of a provided callback on each member of the array, eg.
var oldArray = [1,2,3,4];
var newArray = oldArray.map(function(number){
return number * 2;
});
//newArray = [2,4,6,8]
So in your example it wouldn't work even if response.data was an array as you are not returning anything from the callback.
If response.data is an object you can just add the property direct, eg.
response.data.isLoggedIn = false;
If you could do as developer033 suggests and provide the output of a console.log of response.data that would help identify how best to handle it.
Edit:
Because you are just returning a string try:
vm.dataResponse = {username: response.data, isLoggedIn: true}

Categories