AngularJS: templateUrl is rendering before the controller is free - javascript

Below is the code which making some trouble
angular.module("cattle_feed_frontend", ['ngResource','ngRoute'])
.config(['$routeProvider', function($routeProvider){
$routeProvider.
when('/',
{
controller: 'FeedController',
templateUrl: 'templates/FeedList.html'
}).
otherwise({
redirectTo: '/'
});
}])
.controller('FeedController', function($scope,feeds_factory) {
$scope.feeds = feeds_factory.allFeeds();
})
.factory('feeds_factory',['$http', function($http){
return {
allFeeds : function(){
$http.get("http://localhost:3000/feeds").then(function(response)
{
return response.data;
});
}
}
}])
In controller feeds_factory.allFeeds() making http call to a 3rd party . now when i see my console . It shows that my template is rendered first and then my http is made . Why? and issue due to this behavior is that my template is rendered in which i made the ng-repeat which makes nothing because $scope.feeds is set after its rendering , as follows
<tr ng-repeat="feed in feeds">
<td>
{{feed.ingredient}}
</td>
<td>
{{feed.cost_kg}}
</td>
</tr>

Because $routeProvider doesn't know your controller is going to make a http request, it doesn't know to wait. To tell it you use the resolve property of a route:
$routeProvider.
when('/',
{
controller: 'FeedController',
templateUrl: 'templates/FeedList.html',
resolve: {
feeds: function(feeds_factory) {
return feeds_factory.allFeeds();
}
}
}).
otherwise({
redirectTo: '/'
});
Then return the promise from feeds_factory:
factory('feeds_factory',['$http', function($http){
return {
allFeeds : function(){
return $http.get("http://localhost:3000/feeds").then(function(response) {
return response.data;
});
}
}
}])
Then inject into the controller:
controller('FeedController', function($scope, feeds) {
$scope.feeds = feeds;
})

Most likely you need to change your code to this:
.controller('FeedController', function($scope,feeds_factory) {
feeds_factory.allFeeds()
.then(function(feeds) {
$scope.feeds = feeds;
});
})

Related

AngularJS $http.get with ngRoute how to list details

Maybe someone will help me. I write an app in angularjs, I have a file named list.html which retrieves a list of posts from jsonplaceholder and lists them, with a link to the details of the post. In $ routeParams, I pass the id of the selected one and pick it up. Unfortunately, I have no idea how to download the details of a post and display them in the details.html file. If I want to remove something for example, I write for example $ scope.deletePost as a function and give an id, but how to list details I have no idea.
//routing.js
var myApp = angular.module('myApp', ["ngRoute"])
myApp.config(['$routeProvider',
function ($routeProvider) {
$routeProvider
.when('/test', {
templateUrl: '/event/example.html',
controller: 'exampleController'
}, null)
.when('/list', {
templateUrl: '/event/list.html',
controller: 'exampleController'
}, null)
.when('/test-list', {
templateUrl: '/test/list.html',
controller: 'testController'
}, null)
.when('/test/:id', {
templateUrl: '/test/details.html',
controller: 'testController'
}, null)
}
]);
//controller.js
angular.module('myApp').controller('testController', function ($scope, $http, $routeParams) {
$http.get('https://jsonplaceholder.typicode.com/posts').then(function (response) {
$scope.posts = response.data;
});
$scope.id = $routeParams.id;
});
//details.html
<div data-ng-controller="testController">
{{data}}
</div>
//list.html
<div data-ng-controller="testController">
<ul>
<li ng-repeat="post in posts">
Tytuł: {{post.title}} <a href="#!test/{{post.id}}" >Show</a>
</li>
</ul>
</div>
Check out this plunkr.
You just need to pass the details using ng-href and then catch in the controller using $routeParams. I hope this would help you with what you were looking for.
var app = angular.module( 'mainApp', ['ngRoute'] );
app.config( function( $routeProvider ) {
$routeProvider
.when( '/main', {
templateUrl: 'list.html',
controller: 'listCtrl'
})
.when('/detail/:id', {
templateUrl: 'detail.html',
controller: 'detailCtrl'
})
.otherwise({
redirectTo: '/main'
});
});
app.controller( 'listCtrl', function( $scope, $http) {
$http.get('https://jsonplaceholder.typicode.com/posts')
.then(function(res){
$scope.data = res.data;
})
});
app.controller( 'detailCtrl', function( $scope,$http, $routeParams) {
$scope.id = $routeParams.id;
$http.get('https://jsonplaceholder.typicode.com/posts/'+$scope.id)
.then(function(res){
$scope.data = res.data;
})
});

How to add get request parameter in Angularjs

How to add get request parameter from url to controller in angularjs
e.g. my request is http://localhost/abc-ang/#!/abc/8 and my controller code is
app.controller('AbcCtrl', function($scope,$http) {
$http.get("src/public/add/:id").then(function(response) {
$scope.abc = response.data;
});
});
I want to replace src/public/add/:id to src/public/add/8
how can I do that dynamically?
My routing configuration is
app.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/abc', {
templateUrl: "tpl/welcome.html"
})
.when('/abc/:wineId', {
templateUrl: 'tpl/abc-details.html',
controller: 'AbcDetailCtrl'
})
.otherwise({ redirectTo: '/abc' });
}]);
You can access URL params in your code with $routeParams:
From your comment your route is:
$routeProvider.when('/abc/:wineId', {
templateUrl: 'tpl/abc-details.html',
controller: 'AbcDetailCtrl'
});
So in your controller, you can get wineId value with:
app.controller('AbcCtrl', function($scope, $http, $routeParams) {
$http.get("src/public/add/" + $routeParams.wineId).then(function (response) {
$scope.abc = response.data;
});
});

Resolve function not being injected in controller [Angular JS]

angular
.module('madkoffeeFrontendApp', [])
.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/articles.html',
controller: 'MainCtrl',
resolve: {
articles: function(articleService,$q) {
// return articleService.getArticles();
return 'boo';
}
}
})
.otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(true);
});
My above code contains the resolve.
angular.module('madkoffeeFrontendApp')
.controller('MainCtrl', ['$scope',
function($scope, articles) {
console.log(articles);
}]);
When I tried to inject articles in the array as shown below, it gives an error but as far as I know that's the correct way to inject a resolve function:
angular.module('madkoffeeFrontendApp')
.controller('MainCtrl', ['$scope','articles',
function($scope, articles) {
console.log(articles);
}]);
My articles resolve function is not being injected. I tried returning just a string (example: 'boo') as shown to test if articles dependency works or not, and it doesn't i.e. it returns undefined. What could be the reason?
Here's a Plunker to demonstrate the resolve message. As you'll see in the example, it's the same structure as the code you posted and should work fine.
Click the about page to see the resolve message.
http://plnkr.co/edit/FomhxYIra5GI7nm1KpGb?p=preview
Code:
var resolveTestApp = angular.module('resolveTestApp', ['ngRoute']);
resolveTestApp.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl : 'pages/home.html',
controller : 'mainController'
})
.when('/about', {
templateUrl : 'pages/about.html',
controller : 'aboutController',
resolve: {
resolveMessage: function() {
return 'This is the resolve message';
}
}
})
});
resolveTestApp.controller('mainController', function($scope) {
$scope.message = 'Everyone come and see how good I look!';
});
resolveTestApp.controller('aboutController', ['$scope', 'resolveMessage', function($scope, resolveMessage) {
$scope.message = resolveMessage;
}]
);
It may be the version of Angular you're using or a problem when you're minifying your code.

Using $rootScope to change background image of body in angular

I am using routes and would like to change my background image when I am on a specific route. For some reason the background image does not change/is not reading the value of my rootScope. I make the value true in my controller for the route that needs the different background image. Anyone know what I am doing wrong here? Can I not use $rootScope in my routes to change the class of my body?
HTML:
<body ng-app="ciscoImaDashboardApp" dynamicBodyBg ng-controller="navCtrl" >
JS:
.directive('dynamicBodyBg', function($rootScope, $route){
return {
restrict: 'A',
link: function($scope, el){
$rootScope.$on('$routeChangeSuccess',
function() {
if ($route.current.locals.needToChange()){
el.css({background: url('images/background-bark#2x.jpg')});
}
else {
el.css({background: url('images/background#2x.jpg')});
}
}
);
}
}
});
Routes:
angular.module('ciscoImaDashboardApp', ['ngRoute'])
.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/welcome.html',
controller: 'welcomeCtrl'
})
.when('/overall-results', {
templateUrl: 'views/overall.html',
controller: 'overallCtrl'
})
.when('/swim-lane-results', {
templateUrl: 'views/swim-lane.html',
controller: 'swimlaneCtrl'
})
.when('/key-exemplifiers', {
templateUrl: 'views/key-exemplifiers.html',
controller: 'petalCtrl'
})
.when('/key-exemplifiers/:exemplifier', {
templateUrl: 'views/single-exemplifier.html',
controller: 'keyCtrl',
resolve: {
needToChange: function(){
return true; //or false
}
}
})
.otherwise({
redirectTo: '/'
});
});
If you are using ng-route, you can do the following:
Add this directive to your body element.
app.directive('dynamicBodyBg', function($rootScope, $route){
return {
link: function($scope, el){
$rootScope.$on('$routeChangeSuccess',
function() {
//your router has changed and u can change the background
//add the logic here
if ($route.current.locals.needToChange){
el.css({background: url('//whatever background u want'});
}
else {
el.css({background: url('//restore'});
}
}
);
}
}
});
In your $routeProvider
$routeProvider
.when('/', {
templateUrl: 'views/welcome.html',
controller: 'welcomeCtrl',
resolve: {
needToChange: function(){
return true; //or false
}
}
})
P.S Suggest you to switch to ui-router, which is much easier to understand and maintain.
Solved this by creating a rootScope and changing it for all the views.
$rootScope.backgroundImg = "url('../images/background#2x.jpg')";
And then using it in my view like this:
<body ng-app="ciscoImaDashboardApp" ng-controller="navCtrl" ng-style="
{'background-image': backgroundImg}" >

yeoman angular not rendering views

So, I've been trying to set up an app using Yeoman's official angular gen and this hapijs generator for the backend. Now, so far on the backend I've only got the home route serving the index.html as you can see here
server.route({
method: "GET",
path: "/{param*}",
handler: {
directory: {
path: ["../../client/app", "../../client/bower_components"]
}
},
config: {
auth: false
}
});
next();
};
exports.register.attributes = {
name: 'index'
};
The thing is that worked until I tried to add a new service, controller and view to the angular app, when I did so the views stopped rendering.
Heres the service:
angular.module('graphMeDota2App', [])
.service('MatchesService', ['$httpq', 'config', function ($httpq, config) {
// AngularJS will instantiate a singleton by calling "new" on this function
return {
GetAllMatches: function(){
return $httpq.get(config.steamApiBaseUrl + 'IDOTA2Match_570/GetMatchHistory/v001/?key' + config.steamApiKey + '&accountId' + config.steamAccountId + '&matches_requested=5');
}
};
}]);
Heres the controller:
angular.module('graphMeDota2App')
.controller('MatchesCtrl', ['MatchesService', function ($scope, MatchesService) {
$scope.matches = {};
$scope.getMatches = function(){
MatchesService.GetAllMatches().done(function(response){
$scope.matches = response.data;
});
};
$scope.getHeroPlayed = function(match){
console.log(match);
return 'asdfasdf';
};
}]);
Heres the view:
<div class="jumbotron">
<table>
<tr>
<th>Number</th>
<th>Match Id</th>
</tr>
<tr ng-repeat="match in matches">
<th>{{$index}}</th>
<th>{{match.match_id}}</th>
</tr>
</table>
</div>
And here's my app.js:
angular
.module('graphMeDota2App', [
'ngAnimate',
'ngCookies',
'ngResource',
'ngRoute',
'ngSanitize',
'ngTouch'
])
.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.when('/about', {
templateUrl: 'views/about.html',
controller: 'AboutCtrl'
})
.when('/matches', {
templateUrl: 'views/matches.html',
controller: 'MatchesCtrl'
})
.otherwise({
redirectTo: '/'
});
});
And finally, this is what I get: .
There are no javascript errors, no server sider errors and the views were rendering perfectly before I added my controller/service (both added with the yeoman command line generator).
So, following what Byron Sommardahl said found out the problem was when I was creating my service, specifically this line:
angular.module('graphMeDota2App', [])
.service('MatchesService', ['$httpq', 'config', function ($httpq, config) {
Only thing I did was remove the first "[]" in the first line, then it started working. Any thoughts on why that happened?
angular.module('graphMeDota2App')
.service('MatchesService', ['$http', 'config', function ($http, config) {

Categories

Resources