Changing state does not trigger render - reactjs

I'm having a small issue with a component implementation.
Find the code below
var AroundMe = React.createClass({
getInitialState: function(){
return({
dances: [],
events: this.props.events,
user_coords: {}
})
},
update_events: function(data){
this.setState({events: data});
},
filter_by_geolocation: function(){
var vm = this;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position){
vm.setState({user_coords: {longitude: position.coords.longitude, latitude: position.coords.latitude}});
$.ajax({
url: "/aroundme.json",
datatype: 'JSON',
data: vm.state.user_coords,
method: 'GET'
}).done(function(response){
vm.update_events(response.aroundme);
}.bind(vm));
});
} else {
console.log("geo not supported")
}
},
render: function() {
return(
<div>
<button onClick={this.filter_by_geolocation} className='btn btn-danger'>Locate me</button>
<EventsList events={this.state.events} />
</div>
);
}
});
Clicking on the button changes the events state but does not send the new value to to the Eventslist component.
What did I do wrong?
Thanks for your help!
cheers

I have a hunch. setState is asynchronous so you need to use a callback.
Change this:
vm.setState({user_coords: {longitude: position.coords.longitude, latitude: position.coords.latitude}});
$.ajax({
url: "/aroundme.json",
datatype: 'JSON',
data: vm.state.user_coords,
method: 'GET'
}).done(function(response){
vm.update_events(response.aroundme);
}.bind(vm));
To this:
vm.setState({user_coords: {longitude: position.coords.longitude, latitude: position.coords.latitude}}, function() {
$.ajax({
url: "/aroundme.json",
datatype: 'JSON',
data: vm.state.user_coords,
method: 'GET'
}).done(function(response){
vm.update_events(response.aroundme);
}.bind(vm));
});

Related

How to post an array to mvc controller

I want to post java script object to mvc controller
$(document).ready(function () {
var table = $('#my_table_1').DataTable({
"paging": true,
"ordering": true,
"info": true,
"search": true,
"pageLength": 100
});
var d = '';
var data3 = table.on('search.dt', function () {
//number of filtered rows
// console.log(table.rows({ filter: 'applied' }).nodes().length);
//filtered rows data as arrays
d = table.rows({ filter: 'applied' }).data()
});
console.log(table.rows({ filter: 'applied' }).data());
$('#excel2').click(function (e) {
//var data3 = table.on('search.dt', function () {
// console.log(table.rows({ filter: 'applied' }).data());
// console.log(data3);
//});
console.log(d);
$.ajax({
url: '/Administrator/TestDownload',
type: 'POST',
data: {data:d},
cache: false
}).done(function (response) {
alert(d);
});
});
});
//Controller code:
public JsonResult TestDownload(String[] data)
{
return Json(data,JsonRequestBehavior.AllowGet);
}
I am getting null in controller as a data parameter
Expected: Want to get data object from view to controller as a parameter in controller.
Actual: Data parameter in controller is null
You must check your d variable correct array format.
I tested in my side with var d = ["test",2,3] and in controller it get correct data.
$('#excel2').click(function (e) {
//var data3 = table.on('search.dt', function () {
// console.log(table.rows({ filter: 'applied' }).data());
// console.log(data3);
//});
d = ["test",2,3]
console.log(d);
$.ajax({
url: '/Administrator/TestDownload',
type: 'POST',
data: {data:d},
cache: false
}).done(function (response) {
alert(d);
});
});
});
An example that works:
var test = ["This", "is", "a", "test"];
$.ajax({
type: "POST",
traditional: true,
url: "Administrator/TestDownload",
data: { array: test }
}
});
The controller(in VB.net):
Function TestDownload(array As String()) As ActionResult
//do something
End Function
Why not try stringifying the data and setting the contentType
$.ajax({
url: '/Administrator/TestDownload',
data: JSON.stringify({data:d}), // use JSON stringify
type: 'POST',
contentType: "application/json; charset=utf-8", //add this
cache: false
}).done(function (response) {
alert(d);
});
});

AngularJS selectively showing dynamic directives

I created a few directives. When the page load all directives is loaded. All directives appear. I want to show directives when the function is called. For example when $scope.getConsultant is called the consultant directive must be appear. Other directives should not appear. I have too many html template but I didn't write here. How can I control? What is the best way?
Directives
<div class='container'>
<div consultant></div>
<div investment></div>
<div portfolio></div>
</div>
window.ngApp.directive('investment', function () {
return {
templateUrl: 'lib/view/investment.html'
};
});
window.ngApp.directive('consultant', function () {
return {
templateUrl: 'lib/view/consultant.html'
};
});
window.ngApp.directive('portfolio', function () {
return {
templateUrl: 'lib/view/portfolio.html'
};
});
AngularJS
var ngApp = angular.module('tapusor', []);
window.ngApp.controller('controllerHome', ['$scope', '$controller',
function ($scope, $controller) {
$scope.lat =25.33544;
$scope.lng =13.21687;
$scope.getConsultant = function () {
$.ajax({
type: 'post',
url: "/",
dataType: 'json',
data: {
lat: $scope.lat,
lng: $scope.lng
},
async: true,
cache: false,
success: function (data) {
$scope.resConsultant = data;
}
});
}
$scope.searchInvestment = function () {
$.ajax({
type: 'post',
url: "/",
dataType: 'json',
async: false,
cache: false,
data: {
lat:$scope.lat,
lng:$scope.lng
},
success: function (data) {
$scope.resInvestment = data;
}
})
}
$scope.portfolio = function () {
$.ajax({
type: 'post',
url: "/",
dataType: 'json',
async: false,
cache: false,
data: {
lat:$scope.lat,
lng:$scope.lng
},
success: function (data) {
$scope.resPortfolio = data;
}
})
}
}
]);
First, Satpal is right, use Angular builtins wherever possible.
You need some variable that you can key off of to determine which directive is currently being 'shown'. Then, on each one, you can use that with ng-if.
<div class='container'>
<div consultant ng-if="$shown == 'consultant'"></div>
<div investment ng-if="$shown == 'investment'"></div>
<div portfolio ng-if="$shown == 'portfolio'"></div>
</div>
This is just a rough example, but hopefully you get the idea.
I'd recommending restructuring this code to take advantage of an ngSwitch.
https://docs.angularjs.org/api/ng/directive/ngSwitch
If the goal is to have other directives not appear, then loading the data, and then using an ngSwitch will do just that.

React Dependent from API

I am searching a lot about this topic but can’t seem to find a answer that clarifies me.
I am trying to make my first react app. I have started with create react app to understand the basics and then moved my app to server side rendering. As I was developing I got in a question. How can I fetch some data from my API before the app gives a answer (server side) so I can put some stuff in there that I really need?
You could use an ajax request to pull the data from API and set that to the state variable of react. So that the state variable will be used during render. You could define a method for this and, you can call that method from componentDidMount() to set the values to the state variable.
var CommentBox = React.createClass({
getInitialState: function() {
return {data : []};
},
loadCommentsFromServer: function() {
$.ajax({
url: this.props.url,
dataType: 'json',
cache: false,
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
handleCommentSubmit: function(comment){
var comments = this.state.data;
var newComments = comments.concat([comment]);
this.setState({data: newComments});
$.ajax({
url: this.props.url,
dataType: 'json',
type: 'POST',
data: comment,
success: function(data) {
console.log(data);
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
componentDidMount: function() {
this.loadCommentsFromServer();
setInterval(this.loadCommentsFromServer(), this.props.pollInterval);
},
render: function() {
return (
<div className='commentBox'>
<h1>Comments</h1>
<CommentList data={this.state.data} />
<CommentForm onCommentSubmit={this.handleCommentSubmit} />
</div>
);
}
});
In the above code sample, I wrote a method loadCommentsFromServer() specifically to pull data from an API. And I call that from componentDidMount() and stored the output from API into state variable. And, I used the state variable during render.
Note: The above code sample may not work on its own. Since, it's dependencies are not resolved.

No data returned in consuming REStful web service using Angularjs

I am beginner learning Angularjs .Please help me with examples for following
script added
javascript -
var app = angular.module('myapp', []);
app.controller('MyCtrl1', ['$scope', 'UserFactory', function ($scope, UserFactory) {
UserFactory.get({}, function (userFactory) {
$scope.time = userFactory.time;
})
}]);
var service = angular.module('apiService', ['ngResource']);
service.factory('UserFactory', function ($resource) {
return $resource('http://time.jsontest.com', {}, {
query: {
method: 'GET',
params: {},
isArray: true
}
})
});
.html file
<body ng-app="myapp">
<divng-controller="MyCtrl1" >
<p>
Result from RESTful service is: {{ time }}
</p>
</div>
</body>
above snippet gives the out put as
Result from RESTful service is : {{time}}
and not the value i am expecting
..Reference : http://draptik.github.io/blog/2013/07/13/angularjs-example-using-a-java-restful-web-service/
I want to write CRUD methods (GET/POST/PUT/DELETE) and I have started with GET.
Thanks
You need to make sure that your main app module injects your service. In your plnkr you have:
var app = angular.module('myapp', []);
where you should really have:
var app = angular.module('myapp', ['apiService']);
This ensures that the service module is injected into your app module, and you can use the UserFactory that you define in that module. For this simple case you could have also simply defined the UserFactory factory on the 'myapp' module as well
It's very close but you have a slight mistake in your app instantiation. It should be the following:
var app = angular.module('myapp', [ 'apiService' ]);
There's a couple other issues I see as well but one thing is I usually do the following for async requests
var promise = UserFactory.get({}).$promise;
promise
.then( function(response) {
$scope.time = userFactory.time;
});
EDIT: Here's an example for named methods for a given ReST service:
return $resource('/api/v2.0/user/lists/:listId',
{},
{
// POST - list create/product addition to list
'addProduct': {
method: 'POST',
isArray: false,
params: {
listId: '#listId',
productId: '#productId'
}
},
'createList': {
method: 'POST',
isArray: false,
params: {
listName: '#listName'
}
},
// GET - list of user lists/list details
'readLists': {
method: 'GET',
isArray: false,
params: {}
},
'readListsWithProductId': {
method: 'GET',
isArray: false,
params: {
productId: '#productId'
}
},
'readListById': {
method: 'GET',
isArray: false,
params: {
listId: '#listId',
sort: '#sort',
flags: true,
extendedInfo: true,
rows: '#rows',
start: '#start'
}
},
// PUT - list renaming
'renameList': {
method: 'PUT',
isArray: false,
params: {
newName: '#listName',
listId: '#listId'
}
},
// DELETE - list deletion/clear/product removal
'removeProduct': {
method: 'DELETE',
isArray: false,
params: {
listId: '#listId',
productId: '#productId'
}
},
'clearList': {
method: 'DELETE',
isArray: false,
params: {
listId: '#listId',
clear: true
}
},
'deleteList': {
method: 'DELETE',
isArray: false,
params: {
listId: '#listId'
}
}
});
You could access it like the following:
Factory.[methodName](payload)

TypeError: Object #<Resource> has no method 'push'

I have searched other solutions but it doesn't work, solution was to put isArray: true, but it doent work. I am working with objects btw. I am getting this message in console, but everything works, data has been send to my backend api. How to remove that error ?
app.factory('Category', function($resource, $http) {
return $resource('http://localhost/api/v1/category/', {id: "#id"},
{
update: {
method: 'POST',
isArray: false
},
save: {
method: 'PUT'
},
query: {
method: 'GET',
params: {id: '#id'},
isArray: false
},
create: {
method: 'POST',
headers: {'Content-Type': 'application/json'}
},
drop: {
method: 'DELETE',
params: {id: '#id'}
}
}
);
});
Here is my function
$scope.createInventory = function(){
Inventory.create($scope.newinfo);
$scope.info.push(Inventory);
};
$scope.info not a array. You must specify $scope.info to array, then you can push any values to $scope.info.
Try this
$scope.info=[];
$scope.createInventory = function(){
Inventory.create($scope.newinfo);
$scope.info.push(Inventory);
};

Resources