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>
Related
I have posted some code which i write while i am learning angularjs. I`ve made a resource file to get rest calls from the back-end and a controller where i am calling this function but i do not know how to call the controller in the index.html file.
controller
(function () {
'use strict';
angular.module('carApp').controller('HomeController',
HomeController);
HomeController.$inject = ['$rootScope', '$scope', 'HomeResourceService'];
function HomeController($rootScope, $scope, HomeResourceService) {
var vm = this;
function loadTestData(key, value) {
vm.test = undefined;
return HomeResourceService.getTestData(key,
value).then(function (response) {
vm.test = response.data;
}).catch(function () {
console.log('Error when try to get test data!');
});
}
}
})();
index.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="UTF-8">
<title>SCARS HOME</title>
</head>
<body ng-app="carApp">
<script
src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.js">
</script>
<script src="app/app.js"></script>
<script src="app/home/home-resource.js"></script>
<script src="app/home/home-controller.js"></script>
</body>
</html>
resource
(function() {
'use strict';
angular.module('carApp').factory('HomeResourceService',
HomeResourceService);
HomeResourceService.$inject = [ '$http' ];
function HomeResourceService($http) {
var service = {};
var getTestDataUrl = '/api/data';
service.getTestData = function(key, value) {
return $http({
method : "GET",
url : getTestDataUrl,
params : {
operator : key,
market : value
}
});
};
return service;
}
})();
you can all controller using ng-controller provided with controller name.In your case it is HomeController.
For example: if you have some login page and you want to call loginController in your login page, you can call it like below code snippet.
<div ng-controller="LoginController as login" class="col-xs-12 loginForm">
<div class="center-deck">
</div>
</div>
and your controller will be like that:-
(function() {
"use strict";
angular.module("login").controller("LoginController", LoginController);
LoginController.$inject = ["$location",'$rootScope', '$window', '$scope'];
function LoginController($location, $rootScope, $window, $scope) {
var _this = this;
$rootScope.showHeader = false;
$scope.loginError = false;
_this.authenticate = authenticate;
function authenticate() {
if($scope.login.username === "mail id" && $scope.login.password === "your password") {
$location.path('/dashboard');
$scope.loginError = false;
} else {
$scope.loginError = true;
$location.path("/login");
}
}
}
})();
It show how you can implement login call functionality in your project.
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
I have a angular module in a separate file
userModule.js
'use strict';
angular.module('users', ['ngRoute','angular-growl','textAngular','ngMaterial','ngMessages','ngImgCrop','ngFileUpload'])
.run(function ($rootScope, $location, $http) {
$http.get('/token')
.success(function (user, status) {
if (user) {
$rootScope.user = user;
}
});
})
I've a controller in a separate another file which uses this module:
userController.js
'use strict';
var usersApp = angular.module('users');
usersApp.controller('usersControllerMain', ['$scope', '$http', '$routeParams','$location', 'growl','$rootScope','$mdDialog','API',
function($scope, $http, $routeParams, $location,growl,$rootScope,$mdDialog,API) {
$scope.action = "none";
$scope.password = '',
$scope.grade = function() {
var size = $scope.password.length;
if (size > 8) {
$scope.strength = 'strong';
} else if (size > 3) {
$scope.strength = 'medium';
} else {
$scope.strength = 'weak';
}
};
i've some dependencies defined in my controller for other uses.
Now i need to test this controller. SO i've written a spec file which i'll run directly in browser. I dont want to use test runners like karma:
jasmine.html
<html>
<head>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/jasmine.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/jasmine.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/jasmine-html.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/boot.js"></script>
<script type="text/javascript" src="https://code.angularjs.org/1.4.8/angular.js"></script>
<script type="text/javascript" src="https://code.angularjs.org/1.4.8/angular-mocks.js"></script>
<script type="text/javascript">
describe('userControllerMain testing', function(){
beforeEach(angular.mock.module('users'));
var $controller;
beforeEach(angular.mock.inject(function(_$controller_){
$controller = _$controller_;
}));
describe('$scope.grade', function() {
it('sets the strength to "strong" if the password length is >8 chars', function() {
var $scope = {};
var controller = $controller('usersControllerMain', { $scope: $scope });
$scope.password = 'longerthaneightchars';
$scope.grade();
expect($scope.strength).toEqual('strong');
});
});
});
</script>
</head>
<body>
</body>
</html>
i took this example from angular docs.
but when i run my jasmine.html in browser it throwing an injector module error as shown below:
. am i doing anything wrong here..??
There's something seriously wrong with the approach that you're following here. You should be mocking the controller inside a beforeEach block rather than an it block.
So this is how your test file should be:
describe('userControllerMain testing', function(){
beforeEach(module('users'));
beforeEach(inject(function($controller, $rootScope) {
$scope = $rootScope.$new();
usersControllerMain = $controller('usersControllerMain', {
$scope: $scope
});
}));
describe('$scope.grade', function() {
it('sets the strength to "strong" if the password length is >8 chars', function() {
$scope.password = 'longerthaneightchars';
$scope.grade();
expect($scope.strength).toEqual('strong');
});
});
});
Hope this helps.
In my angular app.js that's the main controller in my index.html I want to have a function like this:
$scope.login = function (user) {
$scope.authenticating = true;
var config = {
method: 'POST',
url: '/api/Account/Login',
data: {
'userName': user.loginUserName,
'password': user.loginPassword,
'rememberMe': user.loginRememberMe
}
};
$http(config)
.success(function (data) {
authentication.isAuthenticated = true;
authentication.userName = user.loginUserName;
localStorage.isAuthenticated = 'yes';
$scope.template = $scope.templates[1];
$state.transitionTo('home');
})
};
In my controllers that are for templates inside index.html I want to be able to get access to the userName. Can someone tell me how I can do this? Initially I tried setting $scope.user = {} in the app.js and then setting $scope.user.userName but when I open another template and its controller that's inside app.js the $scope.user does not seem to be visible.
You could use a service to share data between controllers
app.service('userService', function() {
var user = {};
setUserName = function(name) {
user.name = name;
};
getUser = function(){
return user;
};
});
Controller that sets data
app.controller('FooController', ['$scope', 'userService',
function ($scope, userService) {
$scope.login = function (user) {
$scope.authenticating = true;
var config = {
method: 'POST',
url: '/api/Account/Login',
data: {
'userName': user.loginUserName,
'password': user.loginPassword,
'rememberMe': user.loginRememberMe
}
};
$http(config)
.success(function (data) {
authentication.isAuthenticated = true;
userService.setUserName(user.loginUserName);
localStorage.isAuthenticated = 'yes';
$scope.template = $scope.templates[1];
$state.transitionTo('home');
})
};
}
]);
Other Controller, that retrieves data
app.controller('BarController', ['$scope', 'userService', function($scope, userService) {
var username = userService.getUser().name
});
Since your retrieval is async, you might need to add some event/callback mechanism to your user service, so the controllers get notified when the name is set / changes.
All child controllers inherit $scope variables from parents
<div ng-controller="c1">
<div ng-controller="c2"></div>
</div>
youApp.controller('c1', ['$scope', function($scope){
$scope.blabla = 1;
}]);
youApp.controller('c2', ['$scope', function($scope){
// $scope.blabla is also 1 here because c2 is a child of c1
}]);
You can store anydata in built-in $rootScope service. Services are singleton in Angular
yourApp.run(['$rootScope', functin($rootScope){
$rootScope.foo = 'bar';
// you can inject $rootScope in any controller you want and use $rootScope.foo
}]);
As #Robin suggest, I also recommend to write your own service for authorization
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.