How can I pass an array to a function - arrays

I have a function that save elements in an array onclick. I mean whe I click on an element, this element sends to the function that save it in an array:
private renderTags(tag: Tags, index: number) {
console.log('SELECTED TAG: ' + this.state.selectedTags.length);
return <div>
<div onClick={(e) => { e.stopPropagation(); this.collectTags (tag); }}>
<p
className={styles.tag}
># {tag.title} <i className="ms-Icon ms-Icon--CirclePlus"></i></p>
</div>
</div>
}
I can see that elments are in fact in the selectedTags array.
This is the collectTags function:
private collectTags(tag: Tags): any {
this.setState({ savingSettings: true, tagActive: true });
let selectedTags: Tags[] = this.state.selectedTags;
selectedTags.push(tag);
this.setState({
selectedTags: selectedTags
});
return selectedTags;
}
No, I have another function that update the state of an array containing the selected elemenents. The problem is that I can't find the way to pass the array to this function:
private saveSettings(newTag: Tags): void {
this.setState({ savingSettings: true, tagActive: true });
let tags: Tags[] = this.state.items;
// Add the new tag to the tags array and update the state
tags.push(newTag);
this.setState({
items: tags,
activeTile: -1
});
var cacheManager = new CacheManager();
cacheManager.set(this.cacheKey, tags);
this.props.provider.saveSettingsData(tags).then(() => {
this.setState({
savingSettings: false
});
});
}
To save the array I am trying to use an onclick event that looks like this:
onClick={this.saveSettings(this.state.selectedTags)}
In VS I am getting this error:
"Argument of type 'Tags[]' is not assignable to parameter of type 'Tags'.
Type 'Tags[]' is missing the following properties from type 'Tags': title, id, defaultTag"
What can I do?
Regards
Americo

private saveSettings(newTag: Tags): void {
this.setState((prevState )=>({
savingSettings: true,
tagActive: true,
items: [...prevState.items,newTag],
activeTile: -1
}));
var cacheManager = new CacheManager();
cacheManager.set(this.cacheKey, tags);
this.props.provider.saveSettingsData(tags).then(() => {
this.setState({
savingSettings: false
});
});
}
and you can call click throu ES6 function
onClick={()=>{this.saveSettings(this.state.selectedTags)}

Related

push object in array ngFor

I need to push object in ngFor but I got error Property 'push' does not exist on type 'Observable<MyDataType[]>'.
Stackblitz demo code
HTML
<div *ngFor='let item of myObservableArray | async'>
{{item.value}}
</div>
Component
getData() {
if (!this.myObservableArray) {
this.myObservableArray = this.myService.getData();
this.myObservableArray.push({"id":3, "value":"value_4"});
}
}
Service
mydata: MyDataType[] = [
{"id":1, "value":"value_1"},
{"id":2, "value":"value_2"},
{"id":3, "value":"value_3"}
];
getData():Observable<MyDataType[]>
{
let data = new Observable<MyDataType[]>(observer => {
setTimeout(() => {
observer.next(this.mydata);
}, 4000);
});
return data;
}
}
Demo I added one more method to service to add or update.
addOrUpdate(item:MyDataType){
var elem=this.mydata.find(element=> element.id==item.id);
if(elem){
elem.value=item.value;
}
else{
this.mydata.push(item);
}
}
and call it inside component
this.myService.addOrUpdate({"id":3, "value":"value_4"});

Remove item from state

I know this question has been asked a lot but I haven't seem to find a solution even tho I've tried different scenarios.
this.state = {
chartTypes: [{name: 'Bar', id: 1},{name: 'Line', id: 2},{name: 'Pie', id: 3},{name: 'Radar', id: 4} ],
selectedChart: [],
}
onSelect = (selectedList, selectedItem) => {
// selectedItem.name returns name of chartTypes, selectedItem.id returns id of chartTypes.
this.setState({
selectedChart: selectedItem.name
})
}
onRemove = (selectedList, removedItem) => {
// removedItem.name returns name of chartTypes, removedItem.id returns id of chartTypes.
}
The select option works fine but I just put it there so you can have a better understanding. onSelect puts every selectedItem.name into selectedChart. On the remove function, how may I remove item from this.state.selectedChart based on the value/index.
I think you can do something like this
let temp = this.state.selectedChart;
temp=temp.filter((item) => item !== removedItem.name);
this.setState({ selectedChart: temp });
var newArray = this.state.selectedChart.filter((el)=>
el.id !==removedItem.id
);
after filter
this.setState({selectedChart:newArray})
Just filter and set backed to state
onRemove = (selectedList, removedItem) => {
let filtered = this.state.chartTypes.filter(list=> list.id !==removedItem.id);
this.setState({ chartTypes: filtered });
}

Iterate over data() returned value

My HTML code is like below
<ul>
<li v-for="item in values">{{ item }}</li>
</ul>
My vue.js code is like below
export default {
data() {
return {
values: {}
}
},
props: ['applicants', 'pageinfo'],
watch: {
applicants (val) {
EventBus.$on('click', function (skillName) {
this.values = val[0];
console.log(this.values); // I am getting output here.
});
},
},
}
I am trying to iterate over the values of val[0]. But I am not getting any output.
Either use arrow function like
applicants (val) {
EventBus.$on('click', (skillName) => {
this.values = val[0];
console.log(this.values); // I am getting output here.
});
},
or save the reference of this before the event handler
applicants (val) {
var _self = this;
EventBus.$on('click', function (skillName) {
_self.values = val[0];
console.log(this.values); // I am getting output here.
});
},

ReactJS How can I push a data from SelectField to an object within an array?

I have an array which you can see below. How can I insert data from a Selectfield into prints.printMethod?
selectedOrder: {
category: {},
product: {},
brand: {},
prints: {
printMethod: {},
height: '',
width: '',
colors: ''
}
}
My code below is the onChange function. I am not sure if I am missing something. I hope someone can help me.
onBrandingsChange = (event, index, value) => {
var newSelect = this.state.selectedOrder;
newSelect.prints.push(value);
this.setState({selectedOrder: newSelect});
}
<SelectField value={this.state.selectedOrder.prints.printMethod} onChange={this.onBrandingsChange}>
{_.map(this.state.brandings, (b) => {
return <MenuItem value={b.name} primaryText={b.name} key={b.id}/>;
})}
</SelectField>
prints is an Object not an array type so push can't be used here.
You can assign the value to the key directly if you wish it to be single depth.
Something like:
onBrandingsChange = (event, index, value) => {
var newSelect = this.state.selectedOrder;
// set it
newSelect.prints.printMethod = value
// or use assign
newSelect.prints = Object.assign(newSelect.prints, { printMethod: value });
this.setState({selectedOrder: newSelect});
}
Of if you wish this to be an array you need to change the types of your selectedOrder state.

React: access data-attribute in <option> tag

I have this select JSX:
<select className="form-control" onChange={this.onChange} value={this.props.value}>
{options}
</select>
with options being:
var options = this.props.options.map((option) => {
return (<option key={option.slug} value={option.slug} data-country={option.country} data-continent={option.continent}>{option.value}</option>);
});
But I can't access the selected data-country of the option selected, since the value is accessed by e.target.value, and e.target.dataset is the dataset of the select tag and not the option selected tag:
onChange: function(e) {
this.props.onChange(this.props.name, e.target.value, e.target.dataset.continent, e.target.dataset.country);
},
Is there a fix on this?
Thanks
I find #bjfletcher even more elegant than mine, but I'll report for the records:
I access the <option> DOM element through e.target.options[e.target.selectedIndex] in the onChange method:
onChange: function(e) {
var dataset = e.target.options[e.target.selectedIndex].dataset;
this.props.onChange(this.props.name, e.target.value, dataset.continent, dataset.country);
},
Not sure of the compatibility though.
I would pass around just the slug:
var options = this.props.options.map(option => {
return (
<option key={option.slug} value={option.slug}>
{option.value}
</option>
);
});
... and then retrieve the data using the slug:
onChange: function(event, index, value) {
var option = this.props.options.find(option => option.slug === value);
this.props.onChange(this.props.name, value, option.continent, option.country);
}
(You'd replace the .find with a forEach or whatever JS you use if not ES6 capable.)
I think your best bet would be to use refs.
var options = this.props.options.map((option) => {
return (<option ref={'option_ref_' + option.slug} ...></option>);
});
onChange: function(e) {
var selectedOption = this.refs['option_ref_' + e.target.value];
selectedOption['data-country']; //should work
...
},

Resources