$Scope doesn't work on subpage - angularjs

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.

Related

how to pass parameter from nodejs to angularjs controller?

I have this in nodejs
res.render('pages/dist/reset', {token:req.params.token});
and i can read it in reset.mustache
<body ng-app="eyeApp" ng-controller="ResetController">
<div id="wrapper">
<div id="layout-static">
<div class="static-content-wrapper">
<div class="static-content">
<div id="wrap" ui-view class="mainview-animation animated"></div>
<!--wrap -->
</div>
<footer role="contentinfo" ng-show="!layoutLoading" ng-cloak>
<div class="clearfix">
<button class="pull-right btn btn-default toUp btn-sm hidden-print" back-to-top style="padding: 1px 10px;"><i class="fa fa-angle-up"></i></button>
</div>
</footer>
</div>
</div>
</div>
{{token}}
</body>
Controller from this file is ResetController.
ResetController:
angular
.module('telcoserv.eye.reset', [
'telcoserv.core.services'
])
.controller('ResetController', ['$scope', '$theme','$http','$state','$window','$stateParams', function($scope,$theme,$http,$state,$window,$stateParams) {
'use strict';
$scope.submit = function(){
alert('123');
alert($scope.token);
}
}]);
alert($scope.token) is undefined.
when i say {{token}} in reset.mustache i can read value but $scope.token i can not read in resetController. Why??
$scope.submit = function(){
alert('123');
alert($scope.token);
$http({
method:'',
data: {json : data}
url: ''
}).then(function(response) {
//Success response
}, function(error) {
//Failed response
});
}
use $http to call your api. in method you can put GET, POST, PUT, DELETE, OPTIONS according to your api.
put your URL.
Put your request body in data as JSON only applicable for PUT, POST, DELETE.
If you don't want to initialize some ways to achieve this and get that as parameter
1. Create a constant service for getting token and inject it as a parameter in your controller . you can refer to this article how to create the constant service
https://lostechies.com/gabrielschenker/2014/01/14/angularjspart-9-values-and-constants/
2.On the route definition of the app , make use of the resolve in the route of the page using this controller and use of the same parameter and inject it as a dependency in your controller.

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

How to send data to view from controller 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.

Can't access the variable from newly created filter variable of ng-repeat in angular

I have a ng-repeat like this :
<a class="item item-avatar" ng-click="loadProfile({{student.pi_id}})"
ng-repeat="student in filteredStudents = (students | filter:model.txtSearch)" >
<img src="./img/man.png">
<h2>{{student.pi_name}}</h2>
<p>{{student.pi_hp}}</p>
</a>
the question is how can I access the filteredStudents variable? as I can't access it by using $scope.filteredStudents; in the controller
When you are applying the filter in view the filtered value is not accessible in controller.
If you need the filtered data in your controller you need to do filtering in your controller like:
$scope.filteredData = $filter('filter')($scope.filteredStudents, $scope.model.txtSearch)
Inject filter in your controller
function YourController($scope, $filter)
{
}
then, use the filter in controller itself
$scope.filteredStudents = $filter('yourFilterName')(model.txtSearch);
then in html,
<a class="item item-avatar" ng-click="loadProfile({{student.pi_id}})" ng-repeat="student in filteredStudents" >...</a>
Check this SO question
Controllers execute before the view is rendered, which is why the controller function $scope is empty when it executes. You could access the $scope.filteredStudents from within an event handler, such as ngClick:
var app = angular.module('app',[]);
app.controller('ctrl', function($scope) {
$scope.test = function() {
alert ($scope.items);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<input type="text" ng-model="name" /> {{name}}
<div ng-repeat="i in items = ([1,2,3,4] | filter:name )">
{{i}}
</div>
<button ng-click="test()">Hey</button>
</div>
Alternatively, you can access $scope.filteredStudents by using $timeout:
app.controller('ctrl', function($scope,$timeout) {
$timeout(function() {
// $scope.filteredStudents is accessible here...
alert($scope.filteredStudents);
});
});
This works because the $timeout hander executes after the view is rendered. The javascript enclosure allows the $timeout handler to execute, and still access the controller's function context.

How do I target just one instance of a nested repeat?

This is probably pretty basic, but I'm going round in circles.
I have a nested controller in a ng-repeat - I would like to trigger an event in an instance of the repeat that will affect only the nested controller in that instance, not the nested controller in all instances.
Here is a basic example to try and make things clearer:
<div ng-controller="PostsCtrl">
<div ng-repeat="post in posts">
<p>{{post.body}}</p>
<div ng-controller="CommentsCtrl">
<div ng-repeat="comment in comments">
<p>{{comments.body}}</p>
<a href ng-click="showComments(post.id)">Show comments</a>
</div
</div>
</div>
</div>
angular.module('myApp')
.controller('PostsCtrl', function ($scope, Restangular) {
var posts = Restangular.all('posts');
posts.getList().then(function(posts) {
$scope.posts = posts;
});
$scope.showComments = function(id) {
$scope.$broadcast('SHOW_COMMENTS', id);
};
});
angular.module('myApp')
.controller('CommentsCtrl', function ($scope, Restangular) {
$scope.$on('SHOW_COMMENTS', function(event, id) {
var post = Restangular.one('posts', id);
post.get().then(function(post) {
$scope.comments = post.comments;
});
});
});
What would happen in this example is that all instances of the comments controller would be populated with the same comments - I just need to be able to target the relevant one. I'm sure I'm missing something pretty fundamental, and probably going about this the wrong way.
Many thanks.
You're broadcasting "SHOW_COMMENTS" to all repeated posts. You need to isolate the scope per Post.
Isolate the scope using ng-controller="PostCtrl".
<div ng-controller="PostsCtrl">
<div ng-repeat="post in posts" ng-controller="PostCtrl">
<p>{{post.body}}</p>
<div ng-controller="CommentsCtrl">
<div ng-repeat="comment in comments">
<p>{{comments.body}}</p>
<a href ng-click="showComments()">Show comments</a>
</div
</div>
</div>
</div>
Move show comments from PostsCtrl to PostCtrl.
angular.module('myApp')
.controller('PostCtrl', function ($scope) {
$scope.showComments = function() {
$scope.$broadcast('SHOW_COMMENTS', $scope.post.id);
};
});
Do you really need to use events? You could use ng-if instead.
Your comments are embedded in each Post anyway so why request them again. In this case you could do like something this...
<div ng-controller="PostsCtrl">
<div ng-repeat="post in posts" ng-controller="PostCtrl">
<p>{{post.body}}</p>
<a href ng-click="toggleComments()">Show comments</a>
<div ng-controller="CommentsCtrl" ng-if="showComments">
<div ng-repeat="comment in post.comments">
<p>{{comments.body}}</p>
</div
</div>
</div>
</div>
Toggle comments...
angular.module('myApp')
.controller('PostCtrl', function ($scope) {
$scope.showComments = false;
$scope.toggleComments = function() {
$scope.showComments = !$scope.showComments;
};
});

Resources