Can't get the datas in angularJs - javascript

I have html page like
<div ng-controller="userListControl">
...
</div>
<div ng-controller="userDetailsControl">
....
</div>
And i have angular Js code is
var userDirectory = angular.module('userDirectory',[]);
userDirectory.controller("userListControl", ['$scope','$http', function($scope, $http)
{
$http.get('data/userData.json').success (function(data){
$scope.users = data;
$scope.users.doClick = function(user,event) {
userInfo(user);
}
});
}]);
function userInfo(users)
{
console.log(user);
userDirectory.controller("userDetailsControl", function($scope)
{
console.log('well')
$scope.user = users;
console.log($scope.user)
});
}
Here Everything is working fine. But when we are calling click event, That userInfo called with particular Data. But Second controller gives an error(angular js Error).
I am new one in angular jS. I dont know this logic is correct or not.
I have list items in first Controller. When we are clicking on list, It gets data from particular list and passed to another design. That design have detailed data. So the 2nd controller shows particular list detailed Section

First, There is no need to declare your controller inside a function - I don't think that you're trying to lazy-load controllers. Make it available to your app when it starts.
Second, you need to pass data to the userDetailsControl controller. There are various ways to do this, but here you could just use the $rootScope.
var userDirectory = angular.module('userDirectory',[]);
userDirectory.controller("userListControl", function($scope, $rootScope, $http)
{
$scope.selectUser = function(user){
$rootScope.selectedUser = user;
}
$http.get('data/userData.json')
.success (function(data){
$scope.users = data;
});
})
.controller("userDetailsControl", function($scope, $rootScope){
$rootScope.$watch("selectedUser", function(newVal){
$scope.user = newVal;
}
}
and in your HTML:
<div ng-controller="userListControl">
<button ng-repeat="user in users" ng-click="selectUser(user)">{{user.name}}</button>
</div>
<div ng-controller="userDetailsControl">
<div>{{user.name}}</div>
<div>{{user.otherDetails}}</div>
</div>

Related

Pass innerText to Angularjs Controller

I am trying to get the inner text of a <p> element in my Angular application and pass it to a method and a view using ng-route. So when a user clicks on the <p> element, the innerText is passed through a method, gets some data back, then returns a new view with the response data returned
<p ng-click="searchUser()">Bob Ross</p>
js
var app = angular.module('app', ['ngRoute'])
.config(['$routeProvider', function($routeProvider){
.when('/searchUser:name', {
templateUrl: 'user-results.html',
controller: 'searchController'
})
app.controller('searchController', function($scope, $routeParams) {
$scope.name = $routeParams.name;
$scope.searchUser = function(){
// do some stuff;
}
});
I'm not sure how to grab the inner text of the <p> tag properly and pass it through the method (I'm likely way off); should I be binding it to my model and then passing as a routeparam?
Any help is appreciated!
I'm assuming you're using $http to get the list of users in your controller, in which case you could do this:
<p ng-repeat="user in users" ng-click="searchUser(user.name)">{{user.name}}</p>
And in your controller:
$scope.searchUser = function(userName){
// do some stuff with userName;
};
You can pass in the $event argument to the searchUser function. You can then use the $event.currentTarget to grab the element. For more details on the $event object, click here.
<p ng-click="searchUser($event)">Bob Ross</p>
$scope.searchUser = function($event){
var username = $event.currentTarget.innerHTML;
}

Accessing ng-hide value of one controller to manipulate ng-style of another controller within a global controller

So I am trying to access the boolean value of ng-hide from one controller to change css properties of another controller using a global controller. Here is the link on jsfiddle: https://jsfiddle.net/dqmtLxnt/
HTML
<div ng-controller="mainCtrl">
<div class="first" ng-style="changeColor" ng-controller="firstCtrl">
{{ accessOne }}
</div>
<div class="second" ng-hide="hideSecond" ng-controller="secondCtrl">
{{ accessTwo }}
</div>
</div>
JS
angular.element(document).ready(function() {
angular.module('app', [])
.controller('mainCtrl', ['$scope', function($scope) {
if ($scope.hideSecond == true) {
$scope.changeColor = {
'color': 'blue'
};
}
}]).controller('firstCtrl', ['$scope', function($scope) {
$scope.accessOne = "One";
}]).controller('secondCtrl', ['$scope', function($scope) {
$scope.accessTwo = "Two";
$scope.hideSecond = true;
}]);
angular.bootstrap(document.body, ['app']);
});
I am able to change both changeColor and hideSecond from mainCtrl but I'm not able to access the value set from secondCtrl in the mainCtrl. I even tried setting hideSecond=true in ng-hide and access it on mainCtrl but to no avail.
Can someone help me on this?
You can use a Angular Service for this, storing the value into a service and than retrieving it from the service in another controller.
In your situation the main controller is loaded before the second controller so it would never know when the value is updated. You can use $watch for this, calling an update function when the $scope is updated.
Here if your fiddle updated: https://jsfiddle.net/dqmtLxnt/2/
Service:
angular.module('app.services', [])
.factory('hide', function() {
// Allows for passing of data between controllers
var x = false;
// Sets savedData to what ever is passed in
function set(data) {
x = data;
}
// Returns saved data
function get() {
return x;
}
return {
set: set,
get: get
}
})
Using it in Main Controller:
$scope.$watch(function () { return hide.get(); },
function (value) {
console.log(value);
$scope.update(value);
});
$scope.update = function(value) {
if (value == true) {
$scope.changeColor = {
'color': 'blue'
};
}
}
Using it in Second Controller:
$scope.hideSecond = true;
hide.set(true);
Make sure you inject the service into the app and the service into the controllers.

How to double bind?

I`m new to angularJS. I have a table, I make a request and output some default data in my tablerows from Controller2. Now I want to make a different request and output other data in the same table,but this time from Controller1. How can I do this ?
Html
<tr ng-repeat="stats in statsFromTable" ng-show="statsFromTable.length > 0">
<td><span ng-bind="stats.PERS"></span></td>
JavaScript
Controller2 -- > $scope.statsFromTable = data.REQUEST_ATTRIBUTES.historyList; // the first default request
Controller1 -- > ???
Don't use $rootScope to share info between controllers. For that purpouse you can use a service.
So your code could look like:
angular.
module('yourAngularModule', []).
controller('MyController', ['$scope','myService', function ($scope, myService) {
$scope.number1 = myService.number;
}]).
controller('MyController2', ['$scope','myService', function ($scope, myService) {
$scope.number2 = myService.number;
}]).
service('myService', [function() {
var service = {
number:0
};
return service;
}]);
})(window.angular);
And then you could bind the data like:
<div ng-controller="MyController">
<h3>Controller 1</h3>
{{number1}} // Will display service.number --> 0
</div>
<div ng-controller="MyController2">
<h3> Controller 2</h3>
{{number2}} // Will display service.number --> 0
</div>
I did a plnkr where you can take a look at how two different controllers share info via service.
you can use $rootScope to do this. here is the example demo for you i have created

how to trigger an event in controller2 based on an action in controller1

Here is the plunkr i have created.
Basically i am facing 2 issues with this piece of code -
I need help loading months in the drop down and
When month is changed in the dropdown from headerController, the sales for that month is displayed in detailController. I am trying to create a dependency between multiple controllers using a service.
I will appreciate any help fixing these 2 issues.
You can use $broadcast service for event purposes. Following is the link which explains the use of $broadcast and communicating between two controllers.
enter code herehttp://plnkr.co/edit/d98mOuVvFMr1YtgRr9hq?p=preview
You could simply achieve this by using $broadcast from one controller in $rootScope and listen that event in $scope using $on. Though I would suggest you to use service that will share data among to controller. Using dot rule will reduce your code. Take a look at below optimized code. Also you could replace your select with ng-repeat with ng-option to save object on select.
Markup
<div data-ng-controller="headerController">
<h3>Select Month</h3>
<select id="month" ng-model="sales.selectedMonth"
ng-options="month.monthId for month in sales.monthlySales">
</select>
</div>
<div data-ng-controller="detailsController">
<h3>Sales for Month</h3>
<div ng-bind="sales.selectedMonth"></div>
</div>
Code
app.service('valuesService', [function() {
var factory = {};
factory.sales = {}
factory.sales.salesForMonthId = 10;
factory.sales.months = [1, 2];
factory.sales.monthlySales = [{monthId: 1,sales: 10}, {monthId: 2,sales: 20}];
factory.sales.selectedMonth = factory.sales.monthlySales[0];
return factory;
}]);
app.controller('headerController', ['$scope', 'valuesService',
function($scope, valuesService) {
$scope.sales = {};
getData();
function getData() {
$scope.sales = valuesService.sales;
}
}
]);
app.controller('detailsController', ['$scope', 'valuesService',
function($scope, valuesService) {
$scope.sales = {};
getData();
function getData() {
$scope.sales = valuesService.sales;
}
}
]);
Demo Plunkr
I can see the months are already loading fine.
For proper data binding to work across service and controller, you would need to bind one level above the actual data, resulting a dot in your expression. This is because javascript doesn't pass by reference for primitive type.
In service:
factory.data = {
salesForMonthId: 0
}
In controller:
app.controller('detailsController', ['$scope', 'valuesService',
function ($scope, valuesService) {
$scope.values = valuesService.data;
}
]);
In template:
<div>{{values.salesForMonthId}}</div>
Plunker

AngularJS Only Show View If Server Data Present

In my regular Javascript I append data to HTML ONLY if there's data from the server, otherwise I just show a simple div saying there's nothing. How can I implement this in AngularJS?
Example:
if (AJAXresult)
$element.append(JSONdata); //JSONdata will contain a list of customer data
else
$element.append('<div>No results</div>');
How can I achieve this in Angular?
The simplest way would be to control for the no data state in your returned view.
<div>
<div ng-if="!hasCustomers">
No Customers Available
</div>
<div ng-if="hasCustomers">
<!-- show some stuff -->
</div>
</div>
Then in your controller you can easily initialize this when you load your data:
angular.module('myApp').controller('MyController', function($scope, myDataService){
$scope.hasCustomers = false;
myDataService.getCustomers()
.then(function(value){
$scope.customers = value.data;
$scope.hasCustomers = customers && customers.length;
});
});
If you want to make sure the data is loaded before your view is ever instantiated, then you can also use the resolve property on your $route
$routeProvider.when('/someRoute/',{
templateUrl: '/sometemplate.html',
controller: 'MyController',
controllerAs: 'ctrl', // <-- Highly recommend you do this
resolve: {
customerData: function(myDataService){
return myDataService.getCustomers();
}
}
});
resolve is basically a hash of functions that return a promise, and can be dependency injected just like everything else. The controller and view will not be loaded until all the resolve promises have been fulfilled.
It will be available in your controller by the same property name you gave it:
angular.module('myApp')
.controller('MyController', function($scope, customerData){
$scope.customers = customerData;
$scope.hasCustomers = customerData && customerData.length;
});

Categories

Resources