Using Angular Grid, I get the ajax get data in console.log. But an empty grid.
The console log reads:
[13:56:11.411] now!!
[13:56:11.412] []
[13:56:11.412] now!!
[13:56:11.556] <there is data returned from console.log(getData); >
This is the js file.
// main.js
var app = angular.module('myApp', ['ngGrid']);
var getData = [];
function fetchData() {
var mydata = [];
$.ajax({
url:'/url/to/hell',
type:'GET',
success: function(data) {
for(i = 0, j = data.length; i < j; i++) {
mydata[i] = data[i];
}
getData = mydata;
console.log(getData);
}
});
}
fetchData();
app.controller('MyCtrl', function($scope) {
console.log('now!!')
console.log(getData)
console.log('now!!')
$scope.myData = getData
$scope.gridOptions = {
data: 'myData',
showGroupPanel: true
};
});
New Js file:
// main.js
var app = angular.module('myApp', ['ngGrid']);
app.controller('MyCtrl', function($scope, $http) {
function fetchData() {
$http({
url:'/url/to/hell',
type:'GET'})
.success(function(data) {
$scope.myData = data;
$scope.gridOptions = {
data: 'myData',
showGroupPanel: true
};
});
}
fetchData();
});
HTML file.
<html ng-app="myApp">
<head lang="en">
<meta charset="utf-8">
<title>Blank Title 3</title>
<link rel="stylesheet" type="text/css" href="http://angular-ui.github.com/ng-grid/css/ng-grid.css" />
<link rel="stylesheet" type="text/css" href="../static/css/style.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
<script type="text/javascript" src="http://angular-ui.github.com/ng-grid/lib/ng-grid.debug.js"></script>
<script type="text/javascript" src="../static/js/main.js"></script>
</head>
<body ng-controller="MyCtrl">
<div class="gridStyle" ng-grid="gridOptions"></div>
</body>
</html>
This would be much easier (and more Angular) if you defined a service for your request. Something along these lines:
angular.module('hellServices', ['ngResource'])
.factory('Hell', function ($resource) {
return $resource('URL/TO/HELL', {}, {
query: { method: 'GET' }
});
});
Make sure to include it in your app:
var app = angular.module('myApp', ['ngGrid', 'hellServices']);
Then you can get a promise for it in your controller:
app.controller('MyCtrl', function($scope, $http, Hell) {
$scope.myData = Hell.query();
And then set the grid options to look at the promise for its data (as you already did):
$scope.gridOptions = {
data: 'myData',
showGroupPanel: true
};
If you do this, you don't have to worry about $scope.$apply because it will be handled for you. This is much cleaner and easier to follow. If you still need a callback to modify the data once it's returned from the server, pass a function to the query() function of your service:
...
$scope.myData = Hell.query(function(hell) {
// code that modifies 'hell'
});
Check out the official docs on Angular Services. The basics are also covered in Step #11 of the official Angular JS tutorial.
Your controller is probably accessing the getData array before the .success is finished. You're accessing the variable right away, outside of a promise function, which is initialized to an empty array.
Why don't you try putting the fetchData function into the controller (for now) and storing the getData directly into $scope.myData in the .success? Maybe even initialize the grid right there too? Not sure if you can do that but if you could it would look like this:
app.controller('MyCtrl', function($scope, $http) {
$scope.myData = '';
$scope.gridOptions = { showGroupPanel: true, data: 'myData' };
function fetchData() {
setTimeout(function(){
$http({
url:'/url/to/hell',
type:'GET'})
.success(function(data) {
$scope.myData = data;
if (!$scope.$$phase) {
$scope.$apply();
}
});
}, 3000);
}
fetchData();
});
(source for some of the $scope apply stuff: https://github.com/angular-ui/ng-grid/issues/39)
Also not sure why you're mixing in jQuery .ajax with angular code ($http will do that), and why none of your javascript has a semicolon.
Related
I'm using AngularJS 1.6.3
I'm trying to get data by id but my angular-side is not working
Server side :
app.get("/user/:id", function(req,res){
testDb.findOne({_id : req.params.id}, function(err, doc){
res.send(doc);
res.statusCode = 200;
});
});
AngularJS side :
var UserCtrl = myApp.controller('UserCtrl', function($scope,$http){
$scope.user = null
$scope.getByID = function() {
$http.get("/user/" + id).then(function(response){
console.log("get");
$scope.user = response.data;
});
}
getByID();
});
I've got an error "id is not defined". But I would like to get it from the URL.
Finally I found the solution by using $routeParams.
Controller :
var UserCtrl = myApp.controller('UserCtrl', function($scope,$http,$routeParams){
$scope.user = null;
var id = $routeParams.id;
$scope.getByID = function() {
$http.get("/user/" + id).then(function(response){
console.log("get");
$scope.user = response.data;
});
}
getByID();
});
pass parameter to the function when you are calling it
$scope.getByID = function(id) {
$http.get("/user/" + id).then(function(response){
console.log("get");
$scope.user = response.data;
});
}
$scope.getByID(10); // pass id
You can use $state to get state parameters.
var UserCtrl = myApp.controller('UserCtrl', function($scope,$http,$state){
$scope.user = null;
$scope.getByID = function() {
$http.get("/user/" + $state.params.id).then(function(response){
console.log("get");
$scope.user = response.data;
});
}
$scope.getByID();
});
I hope this help you.
I suggest you pass your variable using params section like below AngularJS To Node JS
AngularJS Code
$http({
method : "GET",
url : "http://localhost:4800/p",
params:{"tagId":"5"}
}).then(function mySucces(response) {
console.log("success");
}, function myError(response) {
});
Node JS
app.get('/p', function (req, res) {
console.log(req.query.tagId)
console.log("call");
});
Install ui-router.
bower install --save angular-ui-router#0.3.1
Link the script in index.html.
<!doctype html>
<html lang="en_US">
<head>
<script type="text/javascript" language="javascript" charset="utf-8" src="lib/angular.js"></script>
<script type="text/javascript" language="javascript" charset="utf-8" src="lib/angular-ui-router/angular-ui-router.js"></script>
</head>
<body ng-app="myApp">
<div ui-view>
</div>
</body>
</html>
Add the ui router dependency in app.js.
var myApp = angular.module('helloworld', ['ui.router']);
Define the states in config.
You can define a $state to pass id to a page as state parameter.
routes.js
myApp.config(function($stateProvider){
$stateProvider
.state('home', {
url: '/home/:id',
templateURL:'home_page.html',
controller: 'UserCtrl'
}
});
});
userCtrl.js
var UserCtrl = myApp.controller('UserCtrl', function($scope,$http,$stateParams){
$scope.user = null;
$scope.getByID = function() {
$http.get("/user/" + $stateParams.id).then(function(response){
console.log("get");
$scope.user = response.data;
});
}
$scope.getByID();
});
Finally, redirect to the page with id as below
From JavaScript: $state.go('home', { id: '12345' });
From html: <a ui-sref="home({ id: '12345' })">Home</a>
when i debug my controller, it stuck at the initialization of the controller and doesn't get past it
here is the app
var app = angular.module('app', []);
and here is the controller and it's service
app.controller('UsersController', function ($scope, UsersService) {
$scope.User = [];
$scope.Image = [];
$scope.CV = [];
alert("Controller");
$scope.GetUserProfile = function (ID) {
alert("in");
UsersService.GetUserData(ID, function (Result) {
if (Result.success == true) {
$scope.User = Result.Content;
}
});
}
});
app.service('UsersService', function ($http) {
this.GetUserData = function (UserID,callback) {
var req = {
method: 'GET',
url: 'http://localhost:7598/tb/Profile/GetProfileByID',
headers: {
'Authorization': 'No Authentication'
},
params: {
'ID': UserID
}
}
$http(req).success(callback);
}
});
and in html i reference the Angular js file and the App file and the Controller file
here is the HTML
<script src="~/Scripts/angular.min.js"></script>
<script src="~/ScriptControllers/MainApp.js"></script>
<script src="~/ScriptControllers/UsersController.js"></script>
<div class="card hovercard" ng-controller="UsersController">
<div class="card-background" ng-init="GetUserProfile(5)">
It seems that you're missing an ng-app directive in the html, according to the html and js code you've posted. The browser just parses the js code but does not execute it.
<body ng-app="app"> ... </body>
Working example of your code: here
Am pretty new to AngularJS.
I have written a code and its working fine.
Would like to know, is there a way to further shrink the controller.
My index.html file is
<!DOCTYPE html>
<html lang="en-US">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body>
<div ng-app="myApp" ng-controller="customersCtrl">
<input type="text" ng-model="sea" ng-change="newSearch()"/>
<ul>
<li ng-repeat="x in myData">
{{ x.name + ', ' + x.emailid}}
</li>
</ul>
</div>
<script src="js/app.js"></script>
<script src="js/controllers/maincontroller.js"></script>
</body>
</html>
And maincontroller.js is
app.controller('customersCtrl', function($scope, $http) {
$http(
{
url: "http://localhost:8080/cordovaprojects/123m/www/customer.php",
method: "GET",
params: {'name':'powercom'}
})
.then(function(response) {
$scope.myData = response.data.records;
});
$scope.newSearch = function() {
$scope.newSea = $scope.sea;
$http(
{
url: "http://localhost:8080/cordovaprojects/123m/www/customer.php",
method: "GET",
params: {'name':$scope.newSea}
})
.then(function(response) {
$scope.myData = response.data.records;
});
};
});
If you notice I have used the same $http function twice with a difference of param.
Thank you.
As #maurycy noted in his comment, the way to keep the size of your controllers small is to keep commonly used functionality inside of a service. Consider this service:
app.service('Customers',
[ '$http',
function($http) {
return {
byName: byName
};
function byName(name) {
return $http({
url: "http://localhost:8080/cordovaprojects/123m/www/customer.php",
method: "GET",
params: {'name': name}
});
}
}
]
);
You can then use this service in a controller like this:
app.controller('customersCtrl', [
'$scope', 'Customers',
function($scope, Customers) {
$scope.myData = null;
Customers.byName('powercom')
.then(function(response) {
$scope.myData = response;
});
}
]);
Which is quite a bit shorter than what you have now, plus it is separated making it able to be used in any other part of your application (as well as much easier to test). If the endpoint changes, you have only a single spot to change and, since it's used everywhere else already, you're done.
Update
To bind on an ng-click, I'll assume you have an input bound to a local model, as well as a button for which to act as the click target, something like this:
<input type="text" data-ng-model="customerName" />
<button data-ng-click="lookupCustomer()">
Lookup Customer
</button>
Then in your controller, you can define the lookupCustomer function this way:
app.controller('customersCtrl', [
'$scope', 'Customers',
function($scope, Customers) {
$scope.customerName = 'powercom';
$scope.lookupCustomer = lookupCustomer;
$scope.myData = null;
lookupCustomer();
function lookupCustomer() {
Customers.byName($scope.customerName)
.then(function(data) {
// Do something with data
});
}
}
]);
You can add checks inside of lookupCustomer to guard against edge cases (no need to lookup an empty customer name), but this should work for you.
It'll be better if you'll create the service for getting your data.
app.service('dataService', function($http) {
this.get = function get(param) {
return $http({
url: "http://localhost:8080/cordovaprojects/123m/www/customer.php",
method: "GET",
params: {'name': param}
});
}
});
app.controller('customersCtrl', function($scope, dataService) {
dataService.get('powercom').then(function(response) {
$scope.myData = response.data.records
});
$scope.newSearch = function() {
$scope.newSea = $scope.sea;
dataService.get($scope.newSea).then(function(response) {
$scope.myData = response.data.records
});
};
});
And also is not necessary to create a functions in your $scope. You can use "this" and get access for your data in controller by controller name or alias like this:
<div ng-controller="customersController as ctrl"><p ng-click="ctrl.newSearch">Hello</p></div>
I am new to AngularJS, I have used service to get data from back end and received it in controller,now I have to parse those values and dynamically create elements in directive,when I am trying to do so I am getting undefined for values in controller.
app.js:
var app = angular.module('childAid', ["myDirectives"]);
app.controller('headerController', function($scope, headerFactory) {
debugger
headerFactory.getAllChallenges()
.then(function(data) {
$scope.challengeslist = data.header;
});
});
directiveExample.js
var myDirectives = angular.module('myDirectives', []);
myDirectives.directive('headerPicker', function() {
return {
restrict: 'AE',
templateUrl: 'component/views/header.html',
link: function($scope, element, attributes) {
console.log('linking foo ' + $scope.challengeslist);
}
};
});
serviceExample.js:
(function() {
angular .module('childAid').factory('headerFactory', headerFactory);
function headerFactory($http) {
function getAllChallenges() {
debugger
return $http
.get('resources/stubs/details_tree.json')
.then(complete)
.catch(failed);
}
// helper function to handle the resolved promise
function complete(response) {
debugger
return response.data;
}
// helper function to handle the rejected promise
function failed(error) {
console.error(error.statusText);
}
return {
getAllChallenges: getAllChallenges
};
}
headerFactory.$inject = ['$http']; })();
index.html:
<div ng-app="childAid" ng-controller="headerController">
<div class="container">
<h2>Displaying Header</h2>
<header-picker></header-picker>
</div>
I don't know where I am doing wrong,Kindly help I am new to AngularJS.
Have you tried using an isolate scope on your directive. It might work out easier for you if you tried something like this..
DEMO
Obviously I don't have access to your api so I've mocked it using a public dummy api, so you will have to modify this to work with your own server.
The important bits are..
return {
restrict: 'AE',
templateUrl: 'header.html',
scope: {
'challengesList' : '='
}
};
.. in your directive, and
<header-picker challenges-list='challengesList'></header-picker>
.. in your html.
Here's the whole thing for reference. Hope you find it useful. Sorry if you've already tried this.
app.js
var app = angular.module('childAid', ["myDirectives"]);
app.controller('headerController', function($scope, headerFactory) {
debugger
headerFactory.getAllChallenges()
.then(function(response) {
$scope.data = response;
// $scope.challengesList = data.header;
// dummy response has a data.title property,
$scope.challengesList = response.data.title;
});
});
angular
.module('childAid')
.factory('headerFactory', headerFactory);
headerFactory.$inject = ['$http'];
function headerFactory($http) {
function getAllChallenges() {
debugger
// var url = 'resources/stubs/details_tree.json';
// dummy api for demo purposes, obviously delete this
// and uncomment your own url for your own app
var url = 'http://jsonplaceholder.typicode.com/posts/1';
return $http
.get(url)
.catch(failed);
}
// helper function to handle the rejected promise
function failed(error) {
console.error(error.statusText);
}
return {
getAllChallenges: getAllChallenges
};
}
var myDirectives = angular.module('myDirectives', []);
myDirectives.directive('headerPicker', function() {
return {
restrict: 'AE',
templateUrl: 'header.html',
scope: {
'challengesList' : '='
}
};
});
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.2/angular.js" data-semver="1.4.2"></script>
<script src="app.js"></script>
</head>
<body>
<div ng-app="childAid" ng-controller="headerController">
<pre>{{data}}</pre>
<div class="container">
<h2>Displaying Header</h2>
<header-picker challenges-list='challengesList'></header-picker>
</div>
</div>
</body>
</html>
header.html
<p>challengeslist = {{challengesList}}</p>
Can someone crate an example of how I could set a $scope variable from a outside the controller using a factory or service that uses AJAX?
Every time I have tried the AJAX variable returns undefined because the request has not returned yet, so $scope.var is undefined. After the AJAX request returns, $scope.var is still undefined even if I call the service from the Controller. Please help.
Please see demo here http://plnkr.co/edit/JcRY8uHRYaHH33UTH7Bt?p=preview
var app = angular.module("myapp", []);
app.service("dataService", function($http, $q) {
var data = [];
function getData() {
var deffered = $q.defer();
var request = {
url: 'data.json',
method: 'GET'
};
$http(request).then(sucess, error);
function sucess(response) {
deffered.resolve(response.data);
}
function error() {
deffered.reject();
}
return deffered.promise;
}
return {
data: data,
getData: getData
}
})
app.controller('MyControl', function($scope, dataService) {
$scope.data = [];
dataService.getData().then(function(response) {
$scope.data = response;
})
});