This is my method for getting a single user. The console.log prints the right object, but in when i try to access the $scope.user in the HTML I get no response, the tags are empty:
$scope.getByUsername = function (id) {
return $http.get('/api/User/' + id).success(function (data) {
$scope.user = data;
console.log($scope.user);
});
}
HTML:
<input type="text" name="name" ng-model="user.Username" />
<button ng-click="getByUsername(user.Username)">Button</button>
<h4>{{user.Username}}</h4>
<h4>{{user.Name}}</h4>
<h4>{{user.ImageLink}}</h4>
Edit:
var BlogFeedApp = angular.module('blogFeedApp', ['ngRoute', 'ngResource']).
config(['$routeProvider', function ($routeProvider) {
$routeProvider.
when('/', { controller: MainController, templateUrl: 'posts.html' }).
when('/test', { controller: MainController, templateUrl: 'test.html' }).
when('/new-post', { controller: PostController, templateUrl: 'new-post.html' }).
when('/new-user', { controller: UserController, templateUrl: 'new-user.html' }).
otherwise({ redirectTo: '/' });
}]);
Try removing the return keyword on line 2 of your JS.
Use something like following :
$scope.getByUsername = function (id) {
return $http.get('/api/User/' + id).success(function (data) {
$scope.user = data;
console.log($scope.user);
return data;
});
}
This should do the trick.
I think it is because your user is not defined when angularjs bootstrap. Can you try define user outside of $http callback?
$scope.user = {};
$scope.user.Username = "";
$scope.getByUsername = function (id) {
return $http.get('/api/User/' + id).success(function (data) {
$scope.user = data;
console.log($scope.user);
return data;
});
}
Related
I'm trying to update my nav bar every time the route changes, and I've tried this, however it doesn't seem to be working. It's supposed to write bob every time the view changes, but it only writes it when the controller loads.
nav.controller.js
angular.module('app')
.controller('navController', ['$scope', '$state', function ($scope, $state) {
var timeSpan;
$scope.user;
...
// Update when the view changes.
$scope.reload = function () {
$state.reload();
};
$scope.$state = $state;
$scope.$watch('$state.$current.locals.globals.view', function () {
console.log('bob');
$scope.user = userService.get();
});
...
$scope.reroute = function(route){
$state.go(route);
};
}]);
route.js
angular.module('SimPlannerApp')
.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.when('/','/signin');
$stateProvider
.state('signin', {
url: "/signin",
templateUrl: 'views/signin.html',
controller: 'signinController'
})
.state('menu', {
url: "/menu",
templateUrl: 'views/menu.html',
controller: 'menuController',
resolve: {
config: function (configService) {
return configService.getConfig()
.then(function(response){
return response.data;
})
.catch(function(error){
console.log('Error : ', error);
return undefined;
});
}
}
})
.state('view', {
url: '/view/:view',
templateUrl: 'views/view.html',
controller: 'viewController',
resolve: {
view: function ($stateParams, configService) {
return configService.getConfig()
.then(function(response){
var config = response.data;
for (var i = 0; i < config.views.length; i++) {
if (config.views[i].route === $stateParams.view) {
return config.views[i];
}
}
return undefined;
})
.catch(function(error){
console.log('Error : ', error);
return undefined;
});
},
config: function (configService) {
return configService.getConfig()
.then(function(response){
return response.data;
})
.catch(function(error){
console.log('Error : ', error);
return undefined;
});
}
}
})
.state('404', {
url: '{path:.*}',
templateUrl: 'views/404.html',
controller: 'errorController'
});
});
PS:
Propably should mention I'm using AngularJS with ui-router.
Not sure if I fully understand but would it not be better to use $stateChangeSuccess to detect when the route changes? I use this in the .run block
$rootScope.$on('$stateChangeSuccess',
function(event, toState, toParams, fromState, fromParams){ ... })
but you could place this in your Controller
https://github.com/angular-ui/ui-router/wiki
You can handle with $locationChangeStart like below:
$rootScope.$on('$locationChangeStart', function () {
console.log('bob');
});
You should write this in .module.run() function.
angular
.module()
.run(function($rootScope) {
// to Here
})
angular.module('CrudApp', []).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'assets/tpl/lists.html',
controller: ListCtrl
}).
when('/add-user', {
templateUrl: 'assets/tpl/add-new.html',
controller: AddCtrl
}).
otherwise({
redirectTo: '/'
});
}]);
function ListCtrl($scope, $http) {
$http.get('api/users').success(function(data) {
$scope.users = data;
});
}
function AddCtrl($scope, $http, $location) {
$scope.master = {};
$scope.activePath = null;
$scope.add_new = function(user, AddNewForm) {
console.log(user);
$http.post('api/add_user', user).success(function() {
$scope.reset();
$scope.activePath = $location.path('/');
});
$scope.deleteCustomer = function(customer) {
$location.path('/');
if (confirm("Are you sure to delete customer number: " + $scope.fld_Customer_Key) == true)
services.deleteCustomer(customer.customerNumber);
};
$scope.reset = function() {
$scope.user = angular.copy($scope.master);
};
$scope.reset();
};
}
// Delete user
I keep getting the error scope not defined and cannot seem to figure out why. can anybody help me troubleshoot this? All of the other functions are working except the delete customer. I don't know what is causing the error
Working Plunker
Here is it. I've updated your sintax, installed the dependencies and your $scope is working. Look at the Plunker. :)
Markup:
<body ng-app="CrudApp">
<div ng-controller="ListCtrl">
List Controller says what? {{what}}
</div>
<div ng-controller="AddCtrl">
Add Cntroller says What? {{what}}
</div>
</body>
script.js
var app = angular.module('CrudApp', ['ngRoute']);
app.controller('ListCtrl', function ($scope, $http) {
$scope.what = 'Rodrigo souza is beauty';
$http.get('api/users').success(function(data) {
$scope.users = data;
});
});
app.controller('AddCtrl', function ($scope, $http, $location) {
$scope.what = 'Rodrigo souza looks like Shrek';
$scope.master = {};
$scope.activePath = null;
$scope.add_new = function(user, AddNewForm) {
console.log(user);
$http.post('api/add_user', user).success(function() {
$scope.reset();
$scope.activePath = $location.path('/');
});
$scope.deleteCustomer = function(customer) {
$location.path('/');
if (confirm("Are you sure to delete customer number: " + $scope.fld_Customer_Key) == true)
services.deleteCustomer(customer.customerNumber);
};
$scope.reset = function() {
$scope.user = angular.copy($scope.master);
};
$scope.reset();
};
});
Working Plunker
I'm having trouble figuring out how I could pass a parameter to a function that is a part of resolve of ngRoute.
In my case I'm doing stuff with tokens. These tokens are typed, so you cannot use the same token for confirming and email and reseting a password. Here's how my routes are defined:
.when("/confirm/:token", {
controller: "confirmEmailController",
templateUrl: "/app/views/confirmEmail.html",
resolve: {
tokenStatus: getTokenStatus
}
})
.when("/reset/:token", {
controller: "resetPasswordController",
templateUrl: "/app/views/resetPasswordEmail.html",
resolve: {
tokenStatus: getTokenStatus
}
})
Here's the getTokenStatus function that's being called for both of them:
var getTokenStatus = ["$q", "$route", "tokenService", function($q, $route, tokenService)
{
var deferred = $q.defer();
var tokenType = ???? //<-- how do I pass this?
tokenService
.getTokenStatus($route.current.params.token, tokenType)
.success(function(response)
{
deferred.resolve(true);
})
.error(function()
{
deferred.resolve(false);
});
return deferred.promise;
}];
The problem is that in order to avoid code duplication I need to somehow pass the value of the token type, as marked in the code. How could I do that?
I've been messing about with this for the last 2 hours, but can't seem to figure it out.
1. You can try to include token type into route
.when("/:tokenType/:token", {
controller: "confirmEmailController",
templateUrl: "/app/views/confirmEmail.html",
resolve: {
tokenStatus: getTokenStatus
}
})
.when("/:tokenType/:token", {
controller: "resetPasswordController",
templateUrl: "/app/views/resetPasswordEmail.html",
resolve: {
tokenStatus: getTokenStatus
}
})
And then just get it from $route.current.params.tokenType. But it's not clean solution - you should check your URL for validity.
2. You can use function wrapping
$routeProvider.when("/confirm/:token", {
controller: "confirmEmailController",
templateUrl: "/app/views/confirmEmail.html",
resolve: {
tokenStatus: getTokenStatus("confirm")
}
})
.when("/reset/:token", {
controller: "resetPasswordController",
templateUrl: "/app/views/resetPasswordEmail.html",
resolve: {
tokenStatus: getTokenStatus("reset")
}
});
var getTokenStatus = function(tokenType) {
return ["$q", "$route", "tokenService", function($q, $route, tokenService) {
var deferred = $q.defer();
tokenService
.getTokenStatus($route.current.params.token, tokenType)
.success(function(response)
{
deferred.resolve(true);
})
.error(function()
{
deferred.resolve(false);
});
return deferred.promise;
}];
};
3. You can move get-token-status logic into separate servise
$routeProvider.when("/confirm/:token", {
controller: "confirmEmailController",
templateUrl: "/app/views/confirmEmail.html",
resolve: {
tokenStatus: ['tokenStatusGetterService', function(tokenStatusGetterService){
return tokenStatusGetterService("confirm");
}]
}
})
.when("/reset/:token", {
controller: "resetPasswordController",
templateUrl: "/app/views/resetPasswordEmail.html",
resolve: {
tokenStatus: ['tokenStatusGetterService', function(tokenStatusGetterService){
return tokenStatusGetterService("reset");
}]
}
});
//...
.service('tokenStatusGetterService', ["$q", "$route", "tokenService", function($q, $route, tokenService) {
return function(tokenType) {
var deferred = $q.defer();
tokenService
.getTokenStatus($route.current.params.token, tokenType)
.success(function(response)
{
deferred.resolve(true);
})
.error(function()
{
deferred.resolve(false);
});
return deferred.promise;
};
}]);
one way to do it is to put a function on your getTokenStatus service.
this is a simplified example, yet it shows how to pass an argument to your resolve function.
app.factory('getTokenStatus',['$q', '$timeout', '$route', function($q, $timeout, $route){
this.action = function(tokenType) {
var defer = $q.defer();
$timeout(function(){
var res = {
path: $route.current.params.token,
tokenType: tokenType
}
defer.resolve(res);
},1000);
return defer.promise;
}
return this;
}]);
and call it from your resolve object:
app.config(function($routeProvider){
$routeProvider
.when("/123/:token", {
template: "<h1>hello</h1>",
controller: 'testCtrl',
resolve: {
tokenStatus: function(getTokenStatus) {
return getTokenStatus.action('firstToken').then(function(res){
console.log(res);
});
}
}
})
here's a plnkr
I can't find the mistake in my application.
The error stack that i receive is this one:
Error: [ng:areq] Argument 'RepoController' is not a function, got undefined
Here is the code of app.js
(function() {
var app = angular.module('gitHubViewer',["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider.when("/main", {
templateUrl: "main.html",
controller: "MainController"
})
.when("/user/:username", {
templateUrl: "user.html",
controller: "UserController"
})
.when("/repo/:usermane/:reponame", {
templateUrl: "repo.html",
controller: "RepoController"
})
.otherwise({
redirectTo:"/main"
});
});
}());
here is the code of the controller
(function() {
var module = angular.module('gitHubViewer');
var RepoController = function($scope, github, $routeParams) {
var onRepoDetailsComplete = function(data) {
$scope.issues = data;
github.getRepoCotributors($score.username, $scope.reponame).then(onRepoCotributorsComplete,onError);
};
var onRepoCotributorsComplete = function(data) {
$scope.repoContribuors = data;
};
var onError = function(reason) {
$scope.error = reason;
}
$scope.username = $routeParams.username;
$scope.reponame = $routeParams.reponame;
github.getRepoDetails($score.username, $scope.reponame).then(onRepoDetailsComplete,onError);
};
module.controller('RepoController',["$scope","github","$routeParams",RepoController]);
}());
Can you please have a look becuase I really can't find teh mistake that I made.
Regards
Fabio
Where does "$score.username" come from?
github.getRepoDetails($score.username, $scope.reponame)
I think that you are missing a dependency for the $score or you have just misspelled $scope.
Here is my state definition:
.state('sub-topic',{
url:"/topics/:topicId",
templateUrl: "templates/sub-topics.html",
controller: "SubTopicsController"
})
Here is my service
myApp.service('subTopicsService',function($http, $stateParams){
this.getSubTopics = function(){
$http.get('topics/' + $stateParams.topicId + '.json').success(function(data, status, header, config) {
return data;
});
}
})
A part of my controller, that has 'subTopicService' injected
$scope.topicList = subTopicsService.getSubTopics();
The problem is, the $stateParams is undefined in the service.
Specifically I get this error message: Cannot access property :topicId of undefined.
How do I use $stateParams in my service?
This scenario should work. There is a working plunker. Changes I made:
I just restructred the service definition:
myApp.service('subTopicsService', function($http, $stateParams) {
var getSubTopics = function() {
$http.get('topics/' + $stateParams.topicId + '.json ')
.success(function(data, status, header, config) {
return data;
});
};
// to prove, that this service can work with $stateParams
var getStateParams = function() {
return $stateParams;
};
return {
getSubTopics: getSubTopics,
getStateParams: getStateParams,
};
});
Here we get the service injected into controller:
myApp.controller('SubTopicsController', function($scope, $state, subTopicsService) {
$scope.stateParams = subTopicsService.getStateParams();
});
And here is our view, consuming that all:
$stateProvider
.state('sub-topic', {
url: "/topics/:topicId",
//templateUrl: "templates/sub-topics.html",
template: '<div><pre>{{stateParams}}</pre></div>',
controller: "SubTopicsController",
});
See the working plunker for more detauls