ImmutableJS Map, how to iterate over a map and return a modified result - reactjs

I am trying to remove the keys listed in the skipheaders array from the submissionsInForm.
const skipHeaders = [ 'layout', 'modules', 'enabled', 'captcha', 'settings'];
submissionsInForm.map((submission) => {
const updatedSubmission = submission.deleteAll(skipHeaders);
return updatedSubmission;
});
That code doesn't seem to be working, as it is returning the full data. Is there anyway to achieve this without having to converting to Vanilla JS?

blacklist
You could use Map#filter to remove any key/value pairs where the key appears in the blacklist
// where Map is Immutable.Map
const m = Map({a: 1, b: 2, c: 3, d: 4})
const blacklist = ['a', 'b']
m.filter((v,k) => !blacklist.includes(k))
// => {"c": 3, "d": 4}
whitelist
Your object is called submissionsInForm so I'm guessing these are user-supplied values. In such a case, I think it is much better to whitelist your fields instead of blacklisting like we did above
Notice we'll add some more fields to the input m this time but our result will be the same, without having to change the whitelist. This is good when you want to explicitly declare which fields the user can submit – all other fields will be rejected.
const m = Map({a: 1, b: 2, c: 3, d: 4, admin: 1, superuser: true})
const whitelist = ['c', 'd']
m.filter((v,k) => whitelist.includes(k))
// => {"c": 3, "d": 4}

Related

How do I add new values to state using Typescript?

you need to add new values to the array, I can't understand what the problem is.
When you click on a checkbox, you need to get the id of this checkbox and write it to the array of answers for the corresponding question
type Result = number;
interface Answer {
result: Result[];
}
const answers: Answer[] = [];
questions.forEach(() => {
answers.push({
result: [],
});
});
const [currentAnswer, setNewAnswer] = useState<Answer[]>(answers)
const handleChange = (e:React.ChangeEvent<HTMLInputElement>) =>{
// console.log(typeof(currentAnswer),currentAnswer);
if(e.target.checked){
console.log(currentAnswer[currentQuestion].result.push(Number(e.target.id)));
setNewAnswer(
currentAnswer[currentQuestion].result.push(Number(e.target.id) // ERROR HERE
)
...
I got error
const currentAnswer: Answer[]
// Argument of type 'number' is not assignable to parameter of type 'SetStateAction<Answer[]>'
should use .concat() in this situation to return new array
.push() will only return new length which is number and incompatible with the type you make.
setNewAnswer(
currentAnswer[currentQuestion].result.concat(Number(e.target.id)) // ERROR HERE
)
To expand on Mic Fung's answer, push mutates the existing array and doesn't return the new array.
const myArray = [1, 2, 3]
myArray.push(4) // returns 4, which is the new array length
console.log(myArray) // [1, 2, 3, 4]
concat doesn't mutate the existing array, but instead returns a new array
const myArray = [1, 2, 3]
const myNewArray = myArray.concat(4)
console.log(myNewArray) // [1, 2, 3, 4]
console.log(myArray) // [1, 2, 3]
When working with React, you should avoid directly mutating the state. Instead, create new values and pass them to the setState function. This is why functions like concat are preferred over ones like push, as they avoid the mutation.

Flutter - Create list and 'addAll' in same instruction

I'm trying to search a element in the array. When get it i need to append some element of the end of the array.
I try similar to this.
List dataModelo = allMakers //THIS IS THE MAIN ARRRAY
.where((modelo) =>
modelo["fabricante"] ==
fabricante["fabricante"])
.toList()
.addAll([
{
"id": 0,
"fabricante":
'Test,
"modelo":
'Test'
}
]);
But return
The expression here has a type of 'void', and therefore cannot be
used.
So anybody know how can i do that?
SOLUTION:
dataModelo = allMakers
.where((modelo) =>
modelo["fabricante"] ==
fabricante["fabricante"])
.followedBy([
{
"id": 0,
"fabricante":
'TEXT',
"modelo":
'TEXT'
}
]).toList();
Use cascade notation after the .where(/**/).toList() part.
e.g.
final arr = [1, 2, 3];
print(arr.where((a) => a > 2).toList()
..addAll([ 4, 5 ])); // returns [3, 4, 5]
In other words, adding another . to your .addAll part should do the trick.

RxJS create new Observable "Array" from and static array in typescript

I am able to create observable from an array but its type is Observable<number> not Observable<number[]>
getUsers(ids: string[]): Observable<number[]> {
const arraySource = Observable.from([1, 2, 3, 4, 5]);
//output: 1,2,3,4,5
const subscribe = arraySource.subscribe(val => console.log(val));
let returnObserable = Observable.from([1, 2, 3, 4, 5]);
return returnObserable; //error at this line, because of the return type
}
Is there any other way to create observable other than from ?
If you want the entire array to be emitted as a single emissions use Observable.of instead:
const arraySource = Observable.of([1, 2, 3, 4, 5]);
Observable.from iterates the array and emits each item separately while Observable.of takes it as without any further logic.
Alternatively, you could also nest two arrays but that's probably too confusing:
const arraySource = Observable.from([[1, 2, 3, 4, 5]]);

Convert array of objects to object of arrays using lodash

The title is a little bit confusing but I essentially want to convert this:
[
{a: 1, b: 2, c:3},
{a: 4, b: 5, c:6},
{a: 7, b: 8, c:9}
]
into:
{
a: [1,4,7],
b: [2,5,8],
c: [3,6,9]
}
using lodash (requirement). Any ideas???
Here's a solution using lodash that maps across the keys and plucks the values for each key from the data before finally using _.zipOobject to build the result.
var keys = _.keys(data[0]);
var result = _.zipObject(keys, _.map(keys, key => _.map(data, key)));
Look for _.map here
input = [
{a: 1, b: 2, c:3},
{a: 4, b: 5, c:6},
{a: 7, b: 8, c:9}
];
output = {};
_.map(input, function(subarray){
_.map(subarray, function(value, key){
output[key] || (output[key] = []);
output[key].push(value);
});
});
console.log(output);

Immutable.js insert an element through cursor manipulation

I am trying to manipulate an Immutable(3.6.4) cursor by adding and inserting an entry to a list:
var data = Immutable.fromJS({a: {b: [0, 1, 2]}});
var cursor = Cursor.from(data, ['a', 'b'], function(newData){
data = newData;
});
cursor = cursor.push(3);
var newList = cursor.splice(1,0,11);
cursor.update(function(x){return newList;});
console.log(data.toJS().a.b); //Result [0, 11, 1, 2, 3]
Why is it that the cursor.splice is not updating the 'data'?
Now, using withMutation, splice does not seem to work. I have added the results next to the log statements.
var data = Immutable.fromJS({a: {b: [0, 1, 2]}});
var cursor = Cursor.from(data, ['a', 'b'], function(newData){
console.log("Setting Data");
data = newData;
});
cursor.withMutations(function(c){
console.log(c.toJS()); //[0, 1, 2]
c.push(3).toJS();
console.log(c.toJS()); //[0, 1, 2, 3]
var newList = c.splice(1,0,11);
console.log(newList.toJS()); //[11]
console.log(c.toJS());//[]
c.update(function(x){return newList;});
});
What is the right way to achive this?
Response from Lee Byron github issue:
splice() operates similarly to map() and filter() - it cannot be used within a withMutations and also cannot be used to update a cursor.
The right way to insert within an array when using cursors is to refer to the referencing element:
// instead of
parentCursor.get('mylist').splice(...);
// do:
parentCursor.update('mylist', list => list.splice(...));
That same pattern will work for other kinds of map/filter operations as well.

Resources