React - Push array to State - arrays

getInitialState: function() {
p:{'Keeper' : [] , 'Defenders': [] , 'Midfield' : [], 'Forwards' : []}}
}
onUpdatePlayers : function (newState) {
var pos;
if (newState.position.includes('Back')) {
pos = 'Defenders'
} else if (newState.position.includes('Midfield')){
pos = 'Midfield'
} else if (newState.position.includes('Forward')) {
pos = 'Forwards'
} else {
pos = newState.position;
}
this.state.p[pos].push(newState)
}
Basically , I want to push some arrays into multiple state's property.
Somehow, I need to change this code "this.state.p[pos].push(newState)" to using this.setState. I've google it and found something like
this.setState({
p : this.state.p[pos].concat([newState])
});
Obviously, It does not help at all. Can you please advise me on this ?
It will be Big Thanks,
Cheers!!

If you do really need your state to be deeply nested you'll need to replace entire p property with new object. For example using Object.assign
this.setState({
p: Object.assign(this.state.p, {
[pos]: this.state.p[pos].concat(newState)
})
})

Danny Kim, you are missing quotes on the new key you wanted to add. Change your last line to
this.state.p['pos'].push(newState)

Related

React : Pushing result of map() to an array

Hello I am trying to map through an array of objects and push them to a new array.
My ISSUE : only the last item of the object is being pushed to the new array
I believe this has to do with React life cycle methods but I don't know where I should I loop and push the values to the array to get the full list
//My object in an array named states
var states = [{"_id":"Virginia","name":"Virginia","abbreviation":"VN","__v":0},{"_id":"North Carolina","name":"North Carolina","abbreviation":"NC","__v":0},{"_id":"California","name":"California","abbreviation":"CA","__v":0}];
export function StateSelect()
{
**EDIT 1**
const options = [];
function getStates()
{
//This is how I am looping through it and adding to an array
{ states.length > 0 &&
states.map(item =>
(
console.log(`ITEM: ${JSON.stringify(item)}`),
options.push([{ value: `${item.name}`, label: `${item.name}`}])
))
}
}
return( {getStates()}: );
}
Thank you
It looks like your getStates() might not even be returning anything... but assuming it is, I believe you should be able to accomplish this using a forEach() fn in order to push values into your options array... Try adding the following into your map:
states.map((item) => {
console.log(`ITEM: ${JSON.stringify(item)}`);
let processed = 0;
item.forEach((i) => {
options.push([{ value: `${i.name}`, label: `${i.name}`}]);
processed++;
if(processed === item.length) {
// callback fn, or return
}
}
.map usually used to return another result, you could just use .forEach
In fact, you don't really need to declare options at all, just use .map on state to return the result would be fine.
return states.length > 0 && states.map(({ name }) => {
return { value: name, label: name };
});

react filtering an object of arrays

I'm trying to find a better way to remove value pairs of an object that contain an empty string ""
my current state is:
this.state = {
searchParams:{
query: '',
colors: [],
text: '',
legalities: '',
setName: '',
pageSize: 4
}
}
I know this won't work with my state since it isn't an array, but something like this is what i'm trying to achieve right now
var search = this.state.searchParams.filter(function (el) {
return el !== "";
});
could anyone point me in the right direction and explain a better way to do this with an object, thanks :) ?
filter only use for a array, not is a object.
You can try my code
let searchParams =
Object.keys(this.state.searchParams)
.filter( key => this.state.searchParams[key] !== '' );
this.setState({searchParams })
You can use Object.entries and Object.fromEntries.
const filteredObject = Object.fromEntries(
Object.entries(searchParams)
.filter(([key, value]) => value !== "")
);
Will create anew object with all the keys for which the value was "" removed.
You can filter it this way with reduce method. Since it is an object, you have to combine object prototype .keys with array prototype .reduce to filter it.
const searchParams = {
query: '',
colors: [],
text: '',
legalities: '',
setName: '',
pageSize: 4
}
const notEmpty = Object.keys(searchParams).reduce((nonEmptyObj, currentKey) => {
if (searchParams[currentKey] !== '') {
nonEmptyObj[currentKey] = searchParams[currentKey];
}
return nonEmptyObj;
}, {})
console.log(notEmpty);
use Object.keys. In your case like this:
var search = Object.keys(this.state.searchParams).filter(el => {
// do something
})
the most simple way is by using Object.keys method and then iterate the whole object. then check if searchParams[ele] is true and add in another object.
var newObj = {};
Object.keys(this.state.searchParams).forEach(ele => {
if (searchParams[ele]) {
newObj = { ...newObj, [ele]: searchParams[ele] };
}
});
console.log(newObj); // new object generated with empty values eliminated
this.setState({searchParams:newObj})
If you want to filter out empty strings and strings (with white spaces only) as well, then
we have trim the string and then check its length. If its string and its length is 0 after trimming, then its considered as empty and will be filtered out.
const params = this.state.searchParams
Object.keys(this.state.searchParams).filter(key =>
!(typeof params[key] === 'string' && params[key].trim().length === 0)
)
If you don't want to trim, then:
const params = this.state.searchParams
Object.keys(this.state.searchParams).filter(key => params[key] !== '')
I would highly suggest you to not to use semicolon, as it takes space and JS can now ignore semicolon as well. Also, not to use double quotes unless required.

Remove data from array in react native

I am doing file selection and push the data into an array but if the selected data has already exist in the array I want to remove it.
I am pushing my data :
_setSelectedFile(file_uri, file_key){
let selectedFiles = [...this.state.selectedFiles];
selectedFiles.push({ file_uri: file_uri, file_key: file_key });
this.setState({ selectedFiles });
}
The output of my array is something like this :
[
{
file_uri: "ph://9F983DBA-EC35-42B8-8773-B597CF782EDD/L0/001",
file_key: "2"
},
{
file_uri: "ph://CC95F08C-88C3-4012-9D6D-64A413D254B3/L0/001",
file_key: "5"
}
]
I stored the file_key as a reference when removing it later. I saw this answer Delete item from state array in react but not sure how to apply it since the question from the discussion is referring to one-dimensional array.
I tried out some trick and apparently it's working in my case. Hope this helps others too.
_setSelectedFile(file_uri, file_key){
var isExist = false;
var selectedFileKey = null;
let selectedFiles = [...this.state.selectedFiles];
if(this.state.selectedFiles != null){
this.state.selectedFiles.map((data, i)=>{
if(data.file_key === file_key){
isExist = true;
selectedFileKey = i;
}
})
}
if(isExist == true){
selectedFiles.splice(selectedFileKey, 1);
this.setState({selectedFiles: selectedFiles});
} else {
selectedFiles.push({ file_uri: file_uri, file_key: file_key });
this.setState({ selectedFiles });
}
}
So I do mapping and check if the data is already exist then assign isExist = true and store the key value selectedFileKey = i.
With isExist set as true I can proceed with removing the data from my array.

Create objects on Ionic

Good morning!
I've been working with Ionic for a few weeks and I thought I actually understood how typescript and angular works, but I've found myself with a weird trouble that I think it will be very silly...
I'm trying to create an object called pendingWaybills with some properties named waybills, clients and clientWaybills. The thing is that I'm creating it this way:
pendingWaybills: {
waybills: any
clients: any,
clientWaybills: any,
};
I've also tried
pendingWaybills: {
"waybills": any,
"clients": any,
"clientWaybills": any,
};
And some other ways, but when I try to assign a value to this properties I'm getting the following error: TypeError: Cannot set property 'waybills' of undefined
I've also tried to assign some string or integers just to see if it was about the data that I was trying to assign like this.pendingWaybills.waybills = "Hi"; but I'm still getting the same error...
Would be glad to get some help as I think it's all about the way to create the object (and I also think it will be very silly) but I'm so stuck here.
Thank you!
Edit:
Here is where I try to assign the data to the object. (The variable data is a json)
loadPendingWaybills(){
this.loadClients(2)
.then(data => {
this.pendingWaybills.waybills = data;
var preClients = this.pendingWaybills.waybills;
this.clients = [];
for(let i = 0;i < preClients.length; i++){
if(this.pendingWaybills.clients.indexOf(preClients[i].descr1_sped) == -1){
this.pendingWaybills.clients.push(preClients[i].descr1_sped)
}
}
this.pendingWaybills.clientWaybills = [];
for(let i = 0; i < this.pendingWaybills.clients.length; i++){
this.getWaybills(this.pendingWaybills.clients[i], 2)
.then(data => {
if(this.pendingWaybills.clientWaybills[i] != data){
this.pendingWaybills.clientWaybills[i] = data;
}
});
}
});
}
You need to create an empty instance of the object, declaring the properties doesn't create the variable, it only tells your ide which properties it has:
public pendingWaybills = {
waybills: []
clients: [],
clientWaybills: [],
};
In Typescript, doing :
pendingWaybills: {
waybills: any;
clients: any;
clientWaybills: any;
};
will only set pendingWaybills variable type. To declare and assign value to the variable, you must do something like :
pendingWaybills = { // note the "="
waybills: something,
clients: something,
clientWaybills: something,
};
Put this in constructor
constructor() {
this.pendingWaybills = {
waybills: [],
clients: [],
clientWaybills: [],
};
}
Some explanation
It is nested object you can not create right away when you declare it.
For example var xxx = 'hi'; is fine. but if you do var xxx.yyy = 'hi' is not fine, as xxx is not defined before so yyy of xxx will cause error.
You can do
var xxx = {
yyy: 'hi'
};
or you can do
var xxx = {};
xxx.yyy = 'hi';

Firebase - How to update many children and not delete others in AngularFire

I want to use update() on firebase ref to update many children in one operation.
To do this I passed the object with values to change.
Here is the output of console.log(angular.toJson(change,1))
{
"10": {
"otherRubies": 30
},
"11": {
"otherRubies": 30
}
}
At the beginning i have:
Then i do:
var refUsers = new Firebase(FBURL).child('users/');
refUsers.update(change);
So i want to have:
but instead of that i get:
Is there any way to do that ?
Update is not a recursive operation. So it's calling set on the child paths. If you call update at users/, you're saying don't delete any keys under user/ which are not in my data, when you want to say, don't delete any keys in the child records of user/.
Instead, iterate the records and call update on each:
var refUsers = new Firebase(FBURL).child('users/');
for(key in change) {
if( change.hasOwnProperty(key) ) {
refUsers.child(key).update( change[key] );
}
}
With Firebase 3 you can do the update by writing :
update = {};
update['10/otherRubies'] = 30;
update['11/otherRubies'] = 30;
refUsers.update(change);
This way of updating the data is not in the documentation but it worked for me.
This is a sample of recursive update:
function updateRecursively(path, value) {
for (let key in value) {
if (value[key] instanceof Object) {
updateRecursively(`${path}/${key}`, value[key]);
} else {
firebase.database().ref(`${path}/${key}`).set(value[key]);
}
}
}
Usage:
updateRecursively('users', {
"10": {
"otherRubies": 30
},
"11": {
"otherRubies": 30
}
})

Resources