How to send data to view from controller AngularJS - angularjs

I want to send data from api to my view... So I need to take data from get reqest and then send that data to my view on my page.
Here is my controller:
angular.module('commentsApp',['notifications'])
.config(function($routeProvider,$locationProvider) {
$routeProvider.
when('/project/:id', {
controller: 'CommentsCtrl',
template: '<%comments%>'
}).
otherwise({
template: 'aaaaaaa',
redirectTo: '/'
});
})
.controller('CommentsCtrl',function($scope,$http,$routeParams){
$scope.comments = [];
$scope.param = $routeParams.id;
$http.get("/api/comments/"+ $scope.param)
.success(function(data){
$scope.comments = data;
})
.error(function(data){
console.log(data);
});
});
Here is my html:
<div id="comment" ng-app="commentsApp" class="panel-body">
<div ng-view>
<h1><% ng %></h1>
</div>
</div>

You should be declaring your ng-app in the <html> tag. I'm not sure what the <% ng %> is, nor the <% comments %> in your template, but that is not how angular renders data to the view. Since comments is an array, you'll want to use an ng-repeat to display the data.
Something like (in your template)
<ul>
<li ng-repeat="comment in comments">
{{comment}}
</li>
</ul>
The {{comment}} is how angular renders variables, similar to erb's <%= comment %>. Comment, is a local variable for each <li> that gets generated by the ng-repeat, which gets its data from the $scope variable comments.
EDIT: Also you may need to $scope.$apply(); in your CommentsController after you assign $scope.comments = data. Not sure on this point, I haven't got angular's full digest cycle in my head yet.

Related

it just keep loading the same page with angular ngRoute?

I am learning angular by building a simple bookstore web app using nodejs as a restful api server. I built the server and it works fine, but once it comes to the front end I face an issue. I built the main page using angular ngRoute to get the data from the server and presented as following:
the picture and the title and the description angular read it with no problem but once I press the button "View Details" I should be redirected to a details page using the book id from the server.
From the front End the route provider:
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(function($routeProvider){
$routeProvider.when('/',{
controller: 'BooksController',
templateUrl: 'views/books.html'
})
.when('/books',{
controller: 'BooksController',
templateUrl: 'views/books.hrml'
})
.when('/books/details/:id',{
controller: 'BooksController',
templateUrl: 'views/book_details.html'
})
.when('/books/add', {
controller: 'BooksController',
templateUrl: 'views/add_book.html'
})
.when('/books/edit/:id', {
controller: 'BooksController',
templateUrl: 'views/edit_book.html'
})
.otherwise({
redirectTo: '/'
})
});
Books Controller:
var myApp = angular.module('myApp');
myApp.controller('BooksController', ['$scope', '$http', '$location',
'$routeParams', function($scope, $http, $location, $routeParams){
console.log('BooksController loaded...');
$scope.getBooks = function(){
$http.get('/api/books').then(function(response){
$scope.books = response.data;
});
}
$scope.getBook = function(){
var id = $routeParams.id;
$http.get('/api/books/'+id).then(function(response){
$scope.book = response.data;
});
}
}]);
books html where the panel being designed:
<div class="panel panel-default" ng-init="getBooks()">
<div class="panel-heading">
<h3 class="panel-title">Latest Books</h3>
</div>
<div class="panel-body">
<div class="row">
<div ng-repeat="book in books">
<div class="col-md-6">
<div class="col-md-6">
<h4>{{book.title}}</h4>
<p>{{book.description}}</p>
<a class="btn btn-primary"
href="#/books/details/{{book._id}}">View Details</a>
</div>
<div class="col-md-6">
<img class="thumbnail" src="{{book.image_url}}">
</div>
</div>
</div>
</div>
</div>
</div>
This the details book html where by clicking the button it must be redirected to:
details_book.html
<div class="panel panel-default" ng-init="getBook()">
<div class="panel-heading">
<h3 class="panel-title">{{book.title}}</h3>
</div>
<div class="panel-body">
<div class "row">
<div class ="col-md-4">
<img src="{{book.image_url}}">
</div>
<div class ="col-md-8">
<p>{{book.description}}</p>
<ul class="list-group">
<li class="list-group-item">Genre: {{book.genre}}</li>
<li class="list-group-item">Author: {{book.author}}</li>
<li class="list-group-item">Publisher: {{book.publisher}}
</li>
</ul>
</div>
</div>
</div>
</div>
and this is the get request from the server to prove the server working find using a certain id
The error I get once I open the main page:
And this error I get once I press the button:
Note: Once I press the button it give me this url:
http://localhost:3000/#!/#%2Fbooks%2Fdetails%2F599701c1f3da51117535b9ab
where the id is 599701c1f3da51117535b9ab which we can see it in the end of the url. But it should give url exactly such as:
http://localhost:3000/#!/books/details/599701c1f3da51117535b9ab
and once I write this url manually I get to the page which is the details with no problem but once I press the button from the book.html page I get the previews strange url again which is:
http://localhost:3000/#!/#%2Fbooks%2Fdetails%2F599701c1f3da51117535b9ab
Which load no where.
This is the github url for all the documents:
https://github.com/AbdallahRizk/BookStore.git
Any suggestions Please!!
use $rootScope instead of $scope for getBook function
$rootScope.getBook = function(){
var id = $routeParams.id;
$http.get('/api/books/'+id).then(function(response){
$scope.book = response.data;
});
init(getBook);
}
Note: add $rootScope to your BookController
Seems like I have hashprefix !, then my URL should also have ! after hash(#)
href="#!/books/details/{{book._id}}"
Since Angular 1.6 hashprefix is defaulted to !, you can disable this behavior by setting hashPrefix to ''(blank).
.config(['$locationProvider',
function($locationProvider) {
$locationProvider.hashPrefix('');
}
]);
Note: This answer from, #Pankaj Parkar at I get a weird templateURL not as it suppose to give with angular?

ng-repeat causing infinite loop in controller. Setting breakpoint show controller code executed infinitely

I am using Angular-Drywall and ngCart. Not very expert with this Angular and JS thing :D.
This is my html from template (main.tpl.html)
<div class="col-xs-3" ng-repeat="item in products">
<div class="thumbnail">
<img ng-src="{{ item.imageUrl }}">
<h4>{{ item.name }}</h4>
<p>{{ item.snippet }}</p>
<h3 class="price">{{ item.name.length*10-.01 | currency}}</h3>
<ngcart-addtocart id="{{ item.id }}"
name="{{ item.name }}"
price="{{ item.name.length*10-.01 }}"
data="item"
quantity="1"
quantity-max="30">
Add To Cart
</ngcart-addtocart></div>
</div>
And this is my controller
angular.module('app').controller('AppCtrl', ['$http', '$scope', 'i18nNotifications', 'localizedMessages', 'ngCart',
function ($http, $scope, i18nNotifications, localizedMessages, ngCart) {
ngCart.setShipping(15.00);
ngCart.setTaxRate(13);
$http({method: 'GET', url: 'data/phones.json'})
.success(function (data, status, headers, config) {
$scope.products = data;
console.log(data);
console.log("LOOP!");
})
.error(function (data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
console.log("ERROR!");
});
$scope.notifications = i18nNotifications;
$scope.removeNotification = function (notification) {
i18nNotifications.remove(notification);
};
$scope.$on('$routeChangeError', function (event, current, previous, rejection) {
i18nNotifications.pushForCurrentRoute('errors.route.changeError', 'error', {}, {rejection: rejection});
});
}]);
I have confirmed ng-repeat is the root cause because removing that code means everything is peachy and no infinite loop.
I have also verify that products is a valid array.
What happen is that, with the html code, the controller keep reloading and executing, consuming resources until Chrome finally ask me to kill it.
Appreciate help. Have been troubleshooting this without much progress few hours now!
EDIT:
The different between working ngCart sample is (using stateProvider and ui.router library)
<div class="container">
<div ui-view></div>
<!-- /.container -->
</div>
while my non working code use this (using routeProvider)
<div class="page">
<div ng-view class="container"></div>
</div>
Code from index.html, showing where the template is inserted. Working one is using ui-view while the non working one is using ng-view.
If this is the reason, appreciate it if someone can explain why.
A problem I had in the past that seems related to your issue:
If you include whatever directive that access a template through "templateUrl" but for some reasons, angular can't resolve the templateUrl of this directive, by default it will return the template for index.html which will contain again your directive and because the templateUrl for the directive is not found, it default again to index.html
and so on....
This is most likely your issue here

ng-repeat not adding new items dynamically

I am new to Angular JS (1) and I am having issues with ng-repeat. I am using socket.io with Angular. Here is my controller:
var messagingApp = angular.module('messagingApp', []);
function mainController($scope) {
var socket = io.connect();
socket.on('message', function(data){
$scope.users.push({'Name': 'yeh'});
console.log($scope.users);
});
$scope.users = []; //if I put stuff here and comment out socket stuff, it shows in the front-end
};
messagingApp.controller('mainController',mainController);
I can see that it is going inside that on block (via console.log). However, it is not displaying anything to the front-end. My front-end is as follows:
<body ng-controller="mainController">
<div ng-repeat="user in users">
<p>{{ user.Name }}</p>
</div>
My understanding is that if you change the model (users in this case), it should automatically update the ng-repeat. Any help would be appreciated.
Add $scope.$apply() after pushing to the array. Because you are updating the model outside of the angular scope. So the angularjs doesnot know the model has been updated. More about $scope.$apply http://tutorials.jenkov.com/angularjs/watch-digest-apply.html
you are pushing the object in array and try to iterate Array. So you should specify the position.
<body ng-controller="mainController">
<div ng-repeat="user in users">
<p>{{ user[$index].Name }}</p>
</div>
or try this..
socket.on('message', function(data){
$scope.users.data.push({'Name': 'yeh'});
console.log($scope.users.data);
});
$scope.users = {data:[]};
<div ng-repeat="user in users.data">
<p>{{ user.Name }}</p>
</div>

$Scope doesn't work on subpage

this is my controller,
.state('tabs.urunler',{
url:'/urunler',
views:{
'urunler-tab':{
templateUrl:'pages/urunler.html',
controller:'MyCtrl'
}
}
})
.state('tabs.detail',{
url:'/urunler/:aId',
views:{
'urunler-tab' : {
templateUrl:'pages/urunlerDetail.html',
controller : 'MyCtrl'
}
}
})
this is POST method.
$http({
url : apiAddress + 'getUrunler',
method : 'POST',
data : {type}
}).then(function successCallback(response){
$scope.urunler = response.data;
console.log($scope.urunler);
},function errorCallback(response){
console.log("error");
});
this is my urunDetails.html
<ion-item ng-repeat="urun in urunler">
{{urun.title}}
<div class="list">
{{urun.brand}}
<a class="item item-thumbnail-left">
<img src ="{{urun.picture}}">
<h2>{{urun.brand}}</h2>
<p>{{urun.title}}</p>
</a>
</div>
this is the Urun.html
<ion-item ng-repeat="urun in urunler">
<div class="list">
<a class="item item-thumbnail-left" ng-click="changeUrun('Alix Avien')" href="#/tab/urunler/{{urun.title}}">
<img src ="{{urun.picture}}">
<h2>{{urun.brand}}</h2>
<p>{{urun.title}}</p>
</a>
</div>
</ion-item>
The problem is , I can reach {{urun}} in Urun.html, but when I go to subpage of urun.html which is urundetails.html, $scope doesn't work :/. I've looked the response data after reached the urunDetails.html by writing console.log(); Data is coming but I can not see data on the urunDetails.html page. Thanks for help !!
This issue is because you are binding data to the scope variable outside angular scope digest cycle. For this scenario you will have to manually trigger the digest cycle.
There are no. of ways to trigger the digest cycle manually.
I will suggest just use $timeout(function(){}, 0); after $scope.urunler = response.data. This will basically trigger the digest cycle once more by taking care of any clashes if there is any digest cycle already running.
Your two states use the same controller, but each controller instance seems to have its own $scope.
I experimented with this here in this plunkr: https://plnkr.co/edit/qGO3pIDHezym71l7jygU?p=preview
angular.module('myApp', []);
angular.module('myApp').controller('ctrl1', ctrl1);
ctrl1.$inject = ['$scope'];
function ctrl1($scope){
$scope.test = 'Something';
$scope.change = function(){
$scope.test = 'Something else';
}
}
and
<body ng-app="myApp">
<div ng-controller="ctrl1">
<p>
{{test}}
</p>
<button ng-click="change()">Click me!</button>
</div>
<div ng-controller="ctrl1">
<p>
{{test}}
</p>
</div>
</body>
The 'change' function only changes the scope variable in the instance where it is called. My best guess is something similar is happening in your case.
You probably want to use some kind of service to provide your controller with the correct data.
Maybe that helps you with your problem, this is just my best guess though. I unfortunately can't really see what you are trying to do with your provided code samples.

template not displaying binded data after routed, on first click - AngularJS

Trying to route to different view template from the index page. Initially, the list on main index page gets loaded and the main.html gets loaded in ng-view, displaying it's text contents. The data from 'MainCtrl' is broadcasted properly and works fine. Now, the confusion is, when the item from the list is clicked, it gets routed to content template(content.html), but the content does not display the binded value on the first click on the list. But, after second click, it starts showing the binded values that is broadcasted from MainCtrl.
<body ng-app="myApp">
<div ng-controller="MainCtrl">
<ul ng-repeat="value in msg" ng-click="setSelectedValue(value)">
<li>
<a href='#/content'>{{ value }}</a>
</li>
</ul>
</div>
<div ng-view=""></div>
main.html:
<p>Select from the list.</p>
content.html:
//loads the selected item from the list on index page
<h3>Selected: {{ message }}</h3>
angular
.module('myApp', ['ngRoute'])
.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.when('/content', {
controller: 'ContentCtrl',
templateUrl: 'views/content.html'
})
.otherwise({
redirectTo: '/'
});
})
.factory('myService', function($http, $rootScope){
var sharedService ={};
sharedService.message = '';
sharedService.prepforBroadcast = function(value){
this.message = value;
this.broadcastItem();
};
sharedService.broadcastItem = function(){
$rootScope.$broadcast ('handleBroadcast');
};
return {
sharedService: sharedService
};
})
.controller('MainCtrl', function ($scope, myService) {
$scope.msg = data; //this will be json data
$scope.selectedValue;
$scope.setSelectedValue = function(value){
$scope.selectedValue = value;
myService.sharedService.prepforBroadcast(value);
}
})
.controller('ContentCtrl', function ($scope, myService) {
$scope.$on('handleBroadcast', function(){
$scope.message = myService.sharedService.message;
})
});
Not sure what exactly is the reason for not binding the data on the very first click even though when the template loads instantly. Any help or thought would be greatly appreciated. Scratching my head for a while.
<ul ng-repeat="value in msg" ng-click="setSelectedValue(value)">
check with out ng-click="setSelectedValue(value)" part. seems like ur click is going to handle by setSelectedValue(value) function
The ng-repeat and ng-click should be on li.
<ul>
<li ng-repeat="value in msg" ng-click="setSelectedValue(value)">
<a href='#/content'>{{ value }}</a>
</li>
</ul>

Resources