Callback function to store values in a Map in ES6 - javascript

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);

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

How to get result from each function inside map function in functional programming/ReactJS?

I am very new to functional programming and having issues with map function. I am trying to call one function on each map call and after every result of that function, I want to get results and give the value of that result to the list I am mapping/looping
Code
customerList = customerList .map(
(customer) =>
(result = getCustomerAddress(customer.id)),
customer.city = result.city,
customer.state = result.state
);
This is not working. It says customer is not defined. I know it is a syntax issue. I am not familiar with functional style of programming. I am trying to just call getCustomerAddress on each Id and then give the values of address to each customer.
There is no declaration of the result variable. You can use destructuring to extract city and state from getCustomerAddress function and then return a new object using the existing customer props along with city and state:
customerList = customerList.map(customer => {
const { city, state } = getCustomerAddress(customer.id);
return { ...customer, city, state };
});
If you still get a customer undefined error, then make sure the customerList array is properly filled with customer data.

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

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.

How to avoid an infinite loop with Observables?

I have the following code:
ngOnInit(): void
{
const source = this.categoryService.getCategories();
console.log(source instanceof Observable);
const example = source.map((categor) => categor.map((categories) => {
const links = this.categoryService.countCategoryLinks(categories.id);
const aff = example.merge(links).subscribe(linke => console.log(linke));
return categories.id
}));
}
where getCategories() returns an observable.
On each item of this Observable, I get categories.id field to run another method called countCategoryLinks(categories.id) that also returns an Observable().
My problem is that : I only have 3 categories (ok), the countCategoryLinks() returns 3 items (ok) but the code above shows an infinite loop in the console.
Both methods started "manually" for testing purpose do not show any loop.
The problem really comes from the code above.
Any idea ?
Thanks in advance and Regards
example.merge(links) <= you are using an observable created by the map callback in the map callback which would cause recursion (ie. loop back into itself). This is where it pays to use proper indention as it is easier to see.
ngOnInit(): void {
const source = this.categoryService.getCategories();
console.log(source instanceof Observable);
const example = source.map((categor) => categor.map((categories) => {
const links = this.categoryService.countCategoryLinks(categories.id);
// this line is the issue. You are using variable example which is being created by the callback this line of code is in
const aff = example.merge(links).subscribe(linke => console.log(linke));
return categories.id
}));
}
I am thinking maybe you did not mean to still be inside of map at this point?

looking for a cleaner way to use scan in rxjs

So I have seen one useful way of using scan where you map a function to the stream to update an initial value.
const initialState = false;
const notThis = (x) => !x;
const toggle = clicks.map(()=> notThis)
.startWith(initialState)
.scan((acc,curr)=> curr(acc))
But if I need the values from clicks I know I can write a partial
const initialState = {klass:'',bool:false};
const toggle = clicks
.map((y)=> {
return (x) => {
let klass = y.target.className;
let bool = !x.bool;
return ({klass, bool});
};
})
.startWith(initialState)
.scan((acc,curr)=> curr(acc));
This could be very useful if I am merging several streams, but it also seem like it could be overly complicated. Is there a better way to accomplish passing data and functions down the stream? Here is a bin of this example link
Well, you should ask yourself if you need to pass down functions. I made your code a bit simpler:
https://jsbin.com/timogitafo/1/edit?js,console,output
Or an even simpler one: https://jsbin.com/giqoduqowi/1/edit?js,console,output

Categories