ctr always undefined in function <reactjs> - reactjs

<script type="text/jsx">
var Counter = React.createClass({
ChangeValue: function(ctr){
alert(this.state.arr[ctr]);
this.setState({
arr : this.state.arr[5]
});
},
getInitialState: function(){
return {
arr:[
'0','0','0',
'0','0','0',
'0','0','0'
],
arr2:[
0,0,0,
0,0,0,
0,0,0]
}
},
render: function(){
var sese = [];
var ctr = 0;
sese.push( <h1>Count: {this.state.arr}</h1>)
for(var i = 0; i < 3 ; i++)
{
for(var j = 0 ; j< 3 ; j++)
{
sese.push(<button type="button" key={ctr} id={ctr} onClick={this.ChangeValue.bind(null, this.ctr)}>{this.state.arr2[ctr]}</button>)
ctr = ctr + 1;
}
sese.push(<br/>)
}
return (
<div>{sese}</div>
);
}
});
ReactDOM.render(
<Counter/>,
document.getElementById('root')
);
</script>
i tried this
var Counter = React.createClass({
ChangeValue: function(ctr){
alert(this.state.arr[this.ctr]);
this.setState({
arr : this.state.arr[5]
});
},
and still undefined..
i'm studying react , get stucked with my ctr in alert , and don't know the solution..
i'm trying to change the value of my button. if i click the button, the value will become 1 but my ctr is always undefined. does anyone know why my alert is always undefined?

In your onClick you have to pass just ctr and not this.ctr as it does not exist.
onClick={this.ChangeValue.bind(null, ctr)}

Related

How to dynamically use object property as width in AngularJS (in ng-repeat)?

I cannot get the object's property to be read in ng-style(shape.radius || shape.length). I can't even get 1 to work at the moment, but would like to have an or statement included. Similar to my ng-class.
There is a button to generate shapes, and the shapes were created with a random size. Here is my code:
html:
<div ng-controller='ShapeController as sc'>
<div>
<p><input type="submit" value="Generate Random Shapes" ng-click="sc.generateShapes()"/></p>
<div ng-repeat="shape in sc.shapes">
<div class="shape" ng-class="{circle: shape.radius, square: shape.length}" ng-style="{'width': shape.length}"></div>
</div>
</div>
</div>
script:
var app = angular.module('app', []);
app.controller('ShapeController', function(){
var vm = this;
vm.shapes = [];
vm.randomShapes = [];
vm.width = 30;
function createCircle(radius) {
let circle = new Circle(radius);
vm.shapes.push(circle);
} // end createCircle
function createSquare(length) {
let square = new Square(length);
vm.shapes.push(square);
} // end createSquare
vm.generateShapes = function() {
let times = 50
for (let i = 0; i < times; i++) {
createCircle(getRandomNumber());
}
for (let i = 0; i < times; i++) {
createSquare(getRandomNumber());
}
sort(vm.shapes);
console.log(vm.shapes);
}; // end generateShapes
}); // end controller
function sort(arr) {
arr.sort(function(a,b){
return b.getArea() - a.getArea();
});
} // end sort function
function getRandomNumber() {
return Math.random() * (100-1) + 1;
}
width should be either in px(some unit like em, pt, etc) or %
ng-style="{'width': shape.length + 'px'}"

Swapping data on ui-grid take a lot of time

I have one grid and according to some conditions, I have to change the data which comes from the back-end.The first time I load data from the back the grid works fine. When I start switching data the grid displays new data well but stays frozen for a while. I notice that this time is random and is often about 3 seconds or plus.
I tried to assign data to the grid through different ways but the result is the same:
1)
$scope.gridOptions = {
//some options,
data: $scope.myData
}
And then
Demande.query({lb: condition}, function (result) {
$timeout(function () {$scope.myData = result;},0);// I also try without $timeout
}
2) I try to assign the data directly to the grid
Demande.query({lb: condition}, function (result) {
$timeout(function () {$scope.gridOptions.data = result;},0);
}
3) I combine the above approachs with
a) $scope.gridApi.core.notifyDataChange(uiGridConstants.dataChange.ROW)
b) $scope.gridApi.core.refreshRows()
but the problem persists. I am using angular-ui-grid 4.0.1
Any idea will be appreciated.
Another option:
4) $scope.gridOptions.data = angular.copy($scope.myData);
Should give the grid the little time that it needs to breath!
Update:
angular.module('app', ['ui.grid'])
.controller('MainCtrl', ['$scope', function($scope) {
$scope.gridOptions = {
columnDefs: []
}
for (var i = 0; i < 80; i++) {
$scope.gridOptions.columnDefs.push({
name: 'C' + (i + 1),
enableColumnMenu: false
});
}
var dataLoadCounter = 1;
$scope.switchData = function() {
$scope.gridOptions.data = [];
for (var i = 0; i < 1000; i++) {
$scope.gridOptions.data.push({});
for (var j = 0; j < 80; j++) {
$scope.gridOptions.data[i]['C' + (j + 1)] = 'D' + dataLoadCounter + (j + 1);
}
}
dataLoadCounter++;
}
$scope.switchData();
}]);
div[ui-grid] {
width: 4500px;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/4.0.2/ui-grid.min.js"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/4.0.2/ui-grid.min.css" />
<div ng-app="app" ng-controller="MainCtrl">
<button ng-click="switchData()">Switch Data</button>
<div ui-grid="gridOptions">
</div>
</div>

reactjs - changing state doesn't re-render component

I'm using a map function to create a game board from an array of objects and calling setState on click to make the game happen. I can successfuly update the state but the view won't update until I perform a different action. I'm guessing the problem is in how the map function passes props to the child element (Cell), but I can't figure out what I'm doing wrong.
var board = [];
var width = 50;
var height = 30;
var size = width * height;
for (var i=1; i<=size; i++) {
board[i] = {id: i, status: 'dead'};
}
var Cell = React.createClass({
turn: function() {
this.props.turn(this.props.id);
},
render: function() {
return <div id={this.props.id} className={this.props.status} onClick={this.turn}></div>
}
});
var GameBoard = React.createClass({
getInitialState: function() {
return {
board: board
};
},
handleClick: function(id) {
var newBoard = this.state.board;
newBoard[id] = {id: id, status: 'alive'};
this.setState({board: newBoard});
},
move: function() {
var board = this.state.board;
var newBoard = board;
for (var j=1;j<=board.length;j++) {
if (board[j].status == 'alive') {
newBoard[j-1] = {id: j-1, status: 'alive'};
newBoard[j] = {id: j, status: 'dead'};
}
}
this.setState({board: newBoard});
},
render: function() {
var squares = this.state.board.map(function(item){
return <Cell id={item.id} status={item.status} turn={this.handleClick}/>
}.bind(this));
return (
<div>
<h1>Game of Life</h1>
<button className="btn btn-default" onClick={this.move}>Run</button>
<div className='boardContainer'>{squares}</div>
</div>
);
}
});
ReactDOM.render(<GameBoard/>,document.getElementById('app'));
http://codepen.io/Theeeus/pen/YpQzPO?editors=0010
The loop in your move function is off-by-one, so it throws an error before reaching the line with setState. The first two lines of the method simply assign a reference to this.state.board in the variable newBoard. Therefore, you're "updating" your state, but not correctly with setState. That's why the board updates on your next click, which calls setState in handleClick.
1) You should modify a deep copy of the state instead of the state itself
2) Fix the off-by-one-error in the for loop
var board = this.state.board;
var newBoard = board; // Note, this is a reference to this.state.board. That's bad!
for (var j=1; j<=board.length - 1; j++) { // note, -1
...
}
You're mutating this.state. The React docs specify that this is a no-no. Inside the GameBoard component, I'd rewrite your handleClick() and move() functions to look more like this:
handleClick: function(id) {
this.setState({
...this.state,
board: [
...this.state.board.slice(0, id),
{
id,
status: 'alive'
},
...this.state.board.slice(id + 1)
]
});
},
move: function() {
this.setState({
...this.state,
board: this.state.board.map((place, id, board) => {
const nextPlace = board[id + 1];
if (nextPlace.status === 'alive') {
return {
...place,
status: 'alive'
};
} else if (place.status === 'alive') {
return {
...place,
status: 'dead'
};
}
return place;
})
});
},
Note: these functions use some new Javascript features like the spread operator (...place) and arrow functions. It's possible that these features might result in syntax errors when you try to run this code.
please use
if(var i = 0;i < arr.length;i++)
,instead of
if(var i = 1;i<=arr.length;i++){}
In your question,when your j in your move function equals to board.length, it will make an error.
Change your two if cycle in your code .
I hope that I can help.
var board = [];
var width = 2;
var height = 3;
var size = width * height;
for (var i=0; i < size; i++) {
board[i] = {id: i, status: 'dead'};
}
var Cell = React.createClass({
turn: function() {
this.props.turn(this.props.id);
},
render: function() {
return <div id={this.props.id} className={this.props.status} onClick={this.turn}></div>
}
});
var GameBoard = React.createClass({
getInitialState: function() {
return {
board: board
};
},
handleClick: function(id) {
var newBoard = this.state.board;
newBoard[id] = {id: id, status: 'alive'};
this.setState({board: newBoard});
},
move: function() {
var board = this.state.board;
var newBoard = board;
for (var j=0;j < board.length;j++) {
if (board[j].status == 'alive') {
newBoard[j-1] = {id: j-1, status: 'alive'};
newBoard[j] = {id: j, status: 'dead'};
}
}
this.setState({board: newBoard});
},
render: function() {
var squares = this.state.board.map(function(item){
return <Cell key = {item.id} fuck={item.id} id={item.id} status={item.status} turn={this.handleClick}/>
}.bind(this));
return (
<div>
<h1>Game of Life</h1>
<button className="btn btn-default" onClick={this.move}>Run</button>
<div className='boardContainer'>{squares}</div>
</div>
);
}
});
ReactDOM.render(<GameBoard/>,document.getElementById('app'));
.dead{
width:10px;height:10px;border:1px solid red;margin:3px;
}
.alive{
border:1px solid green;margin:3px;width:10px;height:10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

Get average from multiple JSON objects values

I have data the following data:
var v = {
"2015-09-23":[
{"AllConversions":"0.1","AverageCpc":"0.01","AverageCpm":"0.02","AveragePosition":"8.3",Id:1},
{"AllConversions":"0.0","AverageCpc":"0.00","AverageCpm":"0.00","AveragePosition":"9.0",Id:1}
],
"2015-09-18":[
{"AllConversions":"0.1","AverageCpc":"77.14","AverageCpm":"239.57","AveragePosition":"7.7",Id:1},
{"AllConversions":"0.0","AverageCpc":"39.97","AverageCpm":"703.91","AveragePosition":"3.8",Id:1},
{"AllConversions":"0.0","AverageCpc":"20.40","AverageCpm":"381.36","AveragePosition":"4.3",Id:1}
]
};
var columns = [
"AllConversions",
"AverageCpc",
"AverageCpm",
"AveragePosition"
];
And I want to return the following object which is the sum of all the fields without Id:
{
"2015-09-23": [
{"AllConversions":"0.1","AverageCpc":"0.01","AverageCpm":"0.02","AveragePosition":"17.3",Id:1}
],
"2015-09-18": [
{"AllConversions":"0.1","AverageCpc":"137.51","AverageCpm":"1324.84","AveragePosition":"15.8",Id:1}
]
}
I tried this code utilising underscrore:
_.each(columns,function(item){
var out = _(groups).map(function (g, key) {
return {
Date: key,
item: _(g).reduce(function (m, x) { return m + x.item; }, 0)
}
});
});
But I get a 'NaN' error when running the code.
Check this out..
<html>
<head>
<script>
var v={
"2015-09-23":[
{"AllConversions":"0.1","AverageCpc":"0.01","AverageCpm":"0.02","AveragePosition":"8.3",Id:1},
{"AllConversions":"0.0","AverageCpc":"0.00","AverageCpm":"0.00","AveragePosition":"9.0",Id:1}
],
"2015-09-18":[
{"AllConversions":"0.1","AverageCpc":"77.14","AverageCpm":"239.57","AveragePosition":"7.7",Id:1},
{"AllConversions":"0.0","AverageCpc":"39.97","AverageCpm":"703.91","AveragePosition":"3.8",Id:1},
{"AllConversions":"0.0","AverageCpc":"20.40","AverageCpm":"381.36","AveragePosition":"4.3",Id:1}
]};
var columns=[
"AllConversions","AverageCpc","AverageCpm","AveragePosition"
];
var output = {};
var smallOutput = {};
var tempDate = [];
for(var i in v){
var temp = 0;
for(var j = 0; j < columns.length ; j++){
for(var k = 0 ; k < v[i].length; k++) temp += parseFloat(v[i][k][columns[j]]);
smallOutput[columns[j]] = temp ;
temp=0;
}
output[[i]] = smallOutput;
}
console.log(output);
</script>
</head>
<body>
</body>
</html>
Here is the fiddle.. https://jsfiddle.net/4t1teyk0/
Check your console.
Here is the output

AngularJs lazyload fadeIn effect

app.controller('reviewCtrl',function($scope,$http) {
$http.get('http://~~~~~~~~~~~~~')
.success(function(data) {
$scope.reviewInfoList = data;
var cnt = 5;
var ind = 0;
$scope.reviewInfo = $scope.reviewInfoList.slice(0,cnt);
$scope.resetList = function(){
ind = 0
$scope.reviewInfo = $scope.reviewInfoList.slice(0,cnt);
};
$scope.loadMore = function() {
ind = ind + cnt
var r = cnt
if (ind + cnt > $scope.reviewInfoList.length) {
r = $scope.reviewInfoList.length - ind
}
$scope.reviewInfo = $scope.reviewInfo.concat($scope.reviewInfoList.slice(ind, r + ind))
}
});
This code is use in My project AngularJS.
I want add fadeIn effect at loadmore function
How to do that
some body help..please
You need to include the ng-animate script, and then when you create your module, include ngAnimate as a dependency. Then the rest is just css. Take a look at this snippet to see it in action.
angular.module('app', ['ngAnimate']).controller('reviewCtrl', function($scope, $http) {
$scope.reviewInfoList = [];
$scope.reviewInfo = [];
var cnt = 2;
var ind = 0;
//for the sake of this demo, generate some dummy data
for (var i = 0; i < 1000; i++) {
$scope.reviewInfoList.push(i);
}
$scope.loadMore = function() {
ind = ind + cnt
var r = cnt
if (ind + cnt > $scope.reviewInfoList.length) {
r = $scope.reviewInfoList.length - ind
}
$scope.reviewInfo = $scope.reviewInfo.concat($scope.reviewInfoList.slice(ind, r + ind))
}
//load the first bit right away
$scope.reviewInfo = $scope.reviewInfoList.slice(0, cnt);
$scope.resetList = function() {
ind = 0
$scope.reviewInfo = $scope.reviewInfoList.slice(0, cnt);
};
});
/* The starting CSS styles for the enter animation */
.fade.ng-enter {
transition: 0.5s linear all;
opacity: 0;
}
/* The finishing CSS styles for the enter animation */
.fade.ng-enter.ng-enter-active {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular-animate.min.js"></script>
<div ng-app="app" ng-controller="reviewCtrl">
<button ng-click="loadMore()">Load more</button>
<ul>
<li class="fade" ng-repeat="review in reviewInfo">{{review}}</li>
</ul>
</div>

Resources