I'm updating the 'backgroundColor' property of the all the objects nested within a sliderSegmentStyleDict state object using the following:
setSliderSegmentStyleDict(prevState => {
let updatedSegmentStyleDict = prevState
for(let segmentIndex in Object.keys(updatedSegmentStyleDict)) {
segmentIndex = Object.keys(updatedSegmentStyleDict)[segmentIndex]
let segmentDict = updatedSegmentStyleDict[segmentIndex]
segmentDict['backgroundColor'] = snappedSegmentIndex > segmentIndex ? '#19486A' : '#d1d5db'
updatedSegmentStyleDict[segmentIndex] = segmentDict
}
return updatedSegmentStyleDict
})
The first time the component renders, it works fine and sets the appropriate colour.
However, when I subsequently invoke this function manually, I get the following error in the console:
Uncaught TypeError: Cannot assign to read only property 'backgroundColor' of object '#<Object>'
Why am I unable to modify the backgroundColor property of segmentDict object?
Related
Uncaught TypeError: Cannot read property 'target' of undefined
Handler for dropdown :
handlePortfolioChange = data => (event) => {
this.resetForm();
this.setState({ selectedPortfolio: event.target.value });
}
Actual SelectBox
<Select value={this.state.sp}
onChange={e =>
this.setState({sp: e.target.value
}, this.handleChange(data, e))}
>
You have a curried function there (it takes multiple sets of arguments). In your case data and event.
You can invoke it like this with both particular sets of arguments at once: handlePortfolioChange(data)(event) (instead of handlePortofolioChange(data,e)).
Maybe it's of help to mention that you can also define a more narrow function with a particular data object to use every time to only have to vary the event like this:
//say, you had data-object that doesn't change in this scope like constantData
constantData = {
"some": 1,
"data": 2,
"here": "idk"
}
// then you could define a more particular function that handlePortfolioChange, by passing //only the first argument to the general function:
handleConstantPortfolioData = handlePortfolioData(constantData);
You could then invoke it anywhere but only worry about the event:
...onChange={e => this.handleConstantPortfolioData(e)}...
I have a quick question about reactjs that hopefully someone can answer. Lets keep it short and sweet.
I have a property in state:
this.state = {
property: []
}
This property is an array. I would like to change one of the properties inside of the array:
this.setState({
property:{
index: value,
}
});
I have 'index' passed as a variable into my state changing function. Index is a number. The value of the index will be something such as '0', '1', '2'... etc.
Doing what I did above will set the value of the property 'index' which is not what I want. How would I instead change the value of the property that has the name stored in the variable 'index'?
You create a copy, assuming index being the position where you want the change to happen and value being the new value you can use this
this.setState({
property: this.state.property.map((anItem, i) => (i === index) ? value : anItem)
});
If your real state happens to have more properties you'll need to use this
this.setState({
...this.state,
property: this.state.property.map((anItem, i) => (i === index) ? value : anItem)
});
I think you are looking for something like this:
const index = 'dummy'
const value = 69
this.setState({
property:{
[index]: value,
}
});
// after the state updated
console.log(this.state.property.dummy); // 66
Do not directly mutate anything in this.state. You are supposed to let React handle that, so make a shallow copy of it and manipulate that.
const newProperty = [...this.state.property];
newProperty[index] = value;
this.setState({property: newProperty});
If you want to use ES5 to make the copy, do this instead:
const newProperty = this.state.property.slice();
I have this code that gets some data from a MongoDB and saves it in an array in my component.
this.laugService.getAllLaug().subscribe(laug => {
this.laugs = laug; //save posts in array
});
this.laugs.array.forEach(element => {
this.modelLaugs.push(new Laug(element.navn, element.beskrivelse))
});
After that i want to save this data to a different array, where i create new instances of my model "Laug". For this i am using a foreach loop, however i am getting an error when running this code:
ERROR Error: Uncaught (in promise): TypeError: Cannot read property
'forEach' of undefined
TypeError: Cannot read property 'forEach' of undefined
I am certain that i receive the data from the DB, however i am unsure why my array is undefined at this point.
Your subscription is asynchronous. The laugs property may not be set when you are trying to iterate. Just put the forEach code inside the subscribe callback:
this.laugService.getAllLaug().subscribe(laug => {
this.laugs = laug; //save posts in array
if (this.laugs && this.laugs.array) {
this.laugs.array.forEach(element => {
this.modelLaugs.push(new Laug(element.navn, element.beskrivelse))
});
}
});
I'm trying to test a function that dynamically determines how many empty rows and columns should be added to a grid. In order to do that I need to set the width of the $document.body. I've so far been able to successfully append and style divs on the body, but not style the body itself. Here's that code:
// Set up the DOM
body = angular.element($document[0].body);
mainColumn = angular.element('<div></div>')[0];
reportGrid = angular.element('<div></div>')[0];
body.append(mainColumn);
body.append(classReportGrid);
// Style elements
mainColumn.style.height = '413px';
mainColumn.style.width = '600px';
reportGrid.style.height = '1000px';
reportGrid.style.width = '1040px';
Here are some approaches I've tried with their corresponding errors bellow:
body.style.width = '800px';
// TypeError: 'undefined' is not an object (evaluating 'body.style.width = '800px'')
body.setAttribute('style', 'width: 800px');
// TypeError: 'undefined' is not a function (evaluating 'body.setAttribute('style', 'width: 800px')')
If I log the body.style, it's undefined. Any advice is appreciated!
I have followed tutorial : http://viralpatel.net/blogs/angularjs-service-factory-tutorial/
But, when I try to save a new record, I am getting newcontact.id as undefined and unable to save new record.
What would be the problem?
you need to add this piece of code
var original = {itemCategory:null,itemName:null,
itemPrice:null,purchaseDate:null,applianceType:null,
insStatus:null,id:null};
$scope.newitem = angular.copy(original);
and edit the saveItem function as this
$scope.saveItem = function () {
alert("add new");
DataStoreService.save($scope.newitem);
$scope.newitem = angular.copy(original);
}
here is the working Plunker
please not that i remove the <script src="angular-dropdowns.min.js"></script> and the ngDropdowns dependency of var app = angular.module('app', ['ngDropdowns']);, to get rid some console errors which are not causing this issue.
The cause of the problem
the problem of getting id undefined is, you didn't define a variable called $scope.newitem with in the controller, instead you straightly use newitem with in the HTML, then your controller dosen't know about this newitem until you change any input.
if you change any input say itemName then the controller knows there is no $scope variable called newitem, then the angular will create the newitem object and a itemName property inside that newitem object , after changing itemName input say u change the itemPrice then the controller search for the newitem object and put the property itemPrice in to the object, ok now you have two properties inside the newitem, like wise the process goes with your inputs, but the id field is a hidden field and your not going to change the value inside html, that means in your newitem object you don't have id property. that`s why its getting undefined.
to scarify,
add a line as the first statement as console.log($scope.newitem); in the $scope.saveItem function and check the $scope.newitem object, here is the Plunker to test it
press save without changing any input
this red color can not read id of undefined error is because we pass the $scope.newitem to the service which is undefined, so the script can not get the id field of item which is undefined in the line of alert("save"+ item.id);). item is undefined
change only the itemName and press save
here you will get a alert saying saveundefined this is because of the alert in line alert("save"+ item.id);). In this line item which is not undefined but the id property of the object is not set , so item.id is undefined, that's why its alert saveundefined. item is defined but item.id is undefined
Solution
create a object to hold default values of all the newitem properties
var original = {itemCategory:null,itemName:null,
itemPrice:null,purchaseDate:null,applianceType:null, insStatus:null,id:null};
get a deep copy of that object and assign it to newitem
$scope.newitem = angular.copy(original);
after saving the newitem reset the newitem object to default object we defined,
$scope.saveItem = function () {
alert("add new");
DataStoreService.save($scope.newitem);
$scope.newitem = angular.copy(original);
}