how to send id from one controller to another in angular - angularjs

I have a basic controller that displays my Software Group name:
var SoftwareGroupApp = angular.module('SoftwareGroupApp', []);
SoftwareGroupApp.controller('SoftwareGroupController', function($scope, $http) {
$http.get("select_SoftwareGroup.php")
.then(function (response) {$scope.result = response.data.records;});
});
In my view I'm displaying this Software Group in a list
<ul class="sub-menu">
<div ng-app="SoftwareGroupApp" ng-controller="SoftwareGroupController">
<li ng-repeat="x in result"><a class="haschild" title="" href="">{{ x.GroupName }}</a>
<ul>
<div ng-controller="SoftwareController">
<li ng-repeat="x in names"><a title="" href="">{{ x.name }}</a></li>
</div>
</ul>
</li>
</div>
</ul>
and i have another controller that display my Software name :
var SoftwareApp = angular.module('SoftwareApp', []);
SoftwareApp.controller('SoftwareController', function($scope, $http) {
$http.get("selectSoftware.php")
.then(function (response) {$scope.names = response.data.records;});
});
when someone click on the Software Group name, i have another sub menu that list my software name .
<ul>
<div ng-controller="SoftwareController">
<li ng-repeat="x in names"><a title="" href="">{{ x.name }}</a></li>
</div>
</ul>
What I'm trying to do is when someone click on the Software Group name, my Software group id save in a variable and send to my SoftwareController . and i display names of software that == id

I would suggest you to use $rootScope.broadcast for this kind of operation. To be very short you can use broadcast like this.
I one controller where you want to send data write like this:
$rootScope.$broadcast("yourFuction", data);
In the receiver controller get this data like this:
$rootScope.$on("yourFuction", function(data){
//do something
});
check this for more information: https://docs.angularjs.org/api/ng/type/$rootScope.Scope
Thanks.

Your best solution would be to use uirouter, rather than ng-controller, and pass the ID as a state parameter.
Another option would be to use components rather than ng-controller, which you can pass parameters to.

There are so many ways. I will mention you one way:
You can create a service to store Id which you want to send into another controller like below:
angular.module('app').factory('commonService', function () {
var myValue;
return {
set: function (o) {
this.myValue = o;
},
get: function () {
return this.myValue;
}
};
});
Now, inject this service into both controller like below:
angular.module('app').controller('firstController', function ($scope, commonService) {
$scope.setValue = function (value) {
commonService.set(value);
};
});
And,
angular.module('app').controller('SecondController', function ($scope, commonService) {
$scope.getValue = function () {
$scope.value = commonService.get();
};
});

Related

html data get from $http GET is not showing properly in Angular js..?

I have defined a controller like this :
app.controller("home", function ($scope, $http, $common) {
$http({
method: "GET",
url: '/posts/loadData'
}).then(function (response) {
//console.clear()
if (typeof response.data.posts != 'undefined') {
console.log(response.data.posts);
$scope.posts = $common.arrangePosts(response.data.posts);
}
});
})
and a service to arrange data :
app.service('$common', function ($timeout, $sce, $httpParamSerializerJQLike) {
var that = this;
this.arrangePosts = function (rawPosts) {
var posts = [];
$.each(rawPosts, function (key, value) {
posts.push({
postId: value.postId,
postLink: '/post/' + that.cleanString(value.title) + '/' + value.postId,
title: value.title,
summary: $sce.trustAsHtml(value.summary)
});
});
return posts;
}
});
using values in html like this :
<div class="widget fullwidth post-single">
<h4 class="widget-title">Latest</h4>
<div class="widget-content">
<ul>
<li ng-repeat="post in posts">
<h4 class="list-title">{{post.title}}</h4>
{{post.summary}}
</li>
</ul>
</div>
</div>
Data coming from server in JSON form :
Object { postId="4", title="asdf", summary="<p>asdf</p>"}
but all the html tags are printing on my page as it is (like a text) in summary.
In many SO posts people suggested to use $sce.trustAsHtml but its not working for me. Please suggest anyway to solve my problem.
Any help will be appreciated..!!
have you tried this?
<div ng-bind-html='post.summary'></div>
You could solve this over a directive. Did you know, that you can use JQuery Lite inside AngularJS to manipulate the DOM?
Here a quick example:
angular.module("PostsDirective",[])
.directive("posts", function($sce){
return {
link: function($scope, $element, $attrs){
//the HTML you want to show
var post = "<div>hello world</div>";
var posts = [post,post,post,post];
//iterating through the list (_.each is a function from underscore.js)
_.each(posts, function(element){
//if you want to save the trusted html string in a var you can do this with getTrustedHtml
//see the docs
var safeHtml = $sce.getTrustedHtml($sce.trustAsHtml(element));
//and here you can use JQuery Lite. It appends the html string to the DOM
//$element refers to the directive element in the DOM
$element.append(safeHtml);
});
}
};
});
And the html
<posts></posts>
This also pretty nice for the readability for your HTML code. And you can use it everywhere on your page.
BTW:
As i can see, you get the HTML elements directly from a REST-Service. Why don't you get just the data and insert it into the ng-repeat? If you transfer all the HTML you get a pretty high overhead if you have loads of data.

Why the value couldn't show in the view after communicate between two controllers?

I met this problem again.Could anybody help me with this?
the first view:
<a type="button" ui-sref="index.usermng.userInfo" ng-click="checkUserInfo(item.id)" class="btn btn-primary">CheckUser</a>
the first controller:
$scope.checkUserInfo = function(userId) {
$rootScope.$broadcast('toUserInfo', userId);
}
the second view:
<div class="tab-pane active tab-chrome" id="tab-chrome">
<div class="row feature">
<div class="col-md-12">
<ul class="list-group">
<li class="list-group-item">UserId:{{data.user.userId}}</li>
<li class="list-group-item">Name:{{data.user.name}}</li>
<li class="list-group-item">Sex:{{data.user.sex}}</li>
<li class="list-group-item">Birthday:{{data.user.birthday | date:'yyyy-MM-dd'}}</li>
<li class="list-group-item">Mobile:{{data.user.mobile}}</li>
</ul>
</div>
</div>
</div>
the second controller:
userApp.controller('userInfoCtrl', ['$scope', '$http', '$rootScope', 'serverUrl', function($scope, $http, $rootScope, serverUrl) {
$rootScope.$on('toUserInfo', function(event, userId) {
console.log(userId); //i can get userId here
$http.get(serverUrl + "/user/info?userId=" + userId).success(function(data) {
console.log(data); // i can get data here
//if (data.code == 0) {
// $scope.detailUserID = userId;
// $scope.detailUserName = data.data.user.name;
// $scope.detailSex = data.data.user.sex;
// $scope.detailBirthday = data.data.user.birthday;
// $scope.detailMobile = data.data.user.mobile;
// $scope.detailCash = data.data.accumulate.usableCash;
$scope.data = data.data
}
//can't show in the view
})
})
}])
the config:
.state('index.usermng.userInfo',{
url: '/userInfo',
templateUrl: 'tpls/userInfo.html',
controller: 'userInfoCtrl'
})
In the second controller,I can get userId from the first controller,and I can get the data,but the view shows nothing,where is wrong?
This is a well known pitfall of Angular. It has to do with the fact that in the template the value is not updated because the scope variables are passed as values and that happens only once, when your view is rendered. That is normal Javascript behaviour.
The way around it is to place all the values on an object. I suggest you do this in your controller:
$scope.data = data.data
and in your templates you change it like this:
<li class="list-group-item">Name:{{data.user.name}}</li>
and so on
A good rule of thumb here is: if there is no dot in the variable in the template, then there is something wrong.
BTW, a more favourable approach is to use controllerAs, which forces you to use a dot in variable names in the template

AngularJS autocomplete from web service

I'm using REST Countries web service and I want to have an autocomplete feature when user is starting to type in input field, and when some country was selected to display an info about it. Want to do it with factories or maybe a directive, don't know what solution is the best
Here is what I have for now:
REST service link: https://restcountries.eu/
HTML:
<div class="container" ng-controller="CountriesController">
<h3 id="title">Countries Database</h3>
<input type="text" id="countrySearch" ng-model="selected" typeahead="country for country in countries | limitTo:8" />
<ng-view></ng-view>
</div>
Template:
<div ng-controller="CountriesController">
<ul>
<li ng-repeat="country in countries" id="countryInfo">
<p><b>Country:</b> {{country.name}}</p>
<p><b>Native Name:</b> {{country.nativeName}}</p>
<p><b>Capital:</b> {{country.capital}}</p>
<p><b>Region:</b> {{country.region}}</p>
<p><b>Subregion:</b> {{country.subregion}}</p>
<p><b>Borders:</b> {{borders}}</p>
<p><b>Languages:</b> {{languages}}</p>
<p><b>Population:</b> {{country.population}} people</p>
<p><b>Area:</b> {{country.area}} sq.km</p>
<p><b>Currencies:</b> {{currencies}}</p>
<p><b>Timezones:</b> {{timezones}}</p>
<p><b>Calling Code:</b> +{{callingCodes}}</p>
</li>
</ul>
Controller:
app.controller('CountriesController', function ($scope, CountriesFactory) {
CountriesFactory.getCountry().then(function (data) {
$scope.selected = undefined;
$scope.countries = data;
console.log($scope.countries);
$scope.timezones = data[0].timezones.toString();
$scope.languages = data[0].languages.toString();
$scope.currencies = data[0].currencies.toString();
$scope.borders = data[0].borders.toString();
$scope.callingCodes = data[0].callingCodes.toString();
});
});
Factory:
app.factory('CountriesFactory', function ($http, $q) {
return {
getCountry: function () {
var input = $('#countrySearch').val();
var request = 'https://restcountries.eu/rest/v1/name/';
var url = request + input;
return $http.get(url);
}
}
});
Checkout bootstrap UI's autocomplete widget
Look at the source code to see how it is implemented
If you go to rest countries here you can see the example how to get the rest countries like: example
The restcountries.eu/rest/v1/name is not working because they don't expose that page.
Try to make sure you have something into input. Try to check if
$('#countrySearch').val();
is not null or empty first.

ng-repeat not working with set data structure

I'm trying to use ng-repeat with a field that is a Set in javascript https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Set. I tried use values(), keys(), entries() method from Set with ng-repat but is not working, anybody know a way, hack for this work?
Resumed code:
function Campaign () {
this.site = {
type : '',
domains : new Set()
};
}
controller:
.controller('CampaignStep1Ctrl', ['$scope', 'languages', 'geoLocationService',
function ($scope, languages, geoLocationService) {
var vm = this;
vm.campaign = $scope.campaign;
}
html:
<tr class="ui-widget-content ui-datatable-empty-message" ng-repeat="domain in vm.campaign.site.domains">
<td colspan="2">{{domain}}</td>
</tr>
Note: If i use console.log() and print domains attribute, it prints, i think that problem only is with ng-repeat.
An ES6 option -
return [...domains];
I used this solution
var devSet = new Set();
devSet.add(""One);
devSet.add(""Two);
...
$scope.deviceTypes = Arrays.from(devSet);
And in html
<ul>
<li ng-repeat="type in deviceTypes">
<p>{{type}}</p>
</li>
</ul>
This is probably not the best solution but you can make it work like this:
View:
<p ng-repeat="value in getSetAsArr(set)">{{ value }}</p>
Controller:
$scope.getSetAsArr = function (set) {
var arr = [];
set.forEach(function (value) {
arr.push(value);
});
return arr;
};

$http.get() loops with ngrepeat

I have 2 entities as below
person {
personID,
personName,
Array of Cars (Person Car)
}
Cars {
carID,
carName
}
And then the relational entity for Person-Car as below
PersonCar {
personID,
CarID,
relatedProperty1,
relatedProperty2
}
Now, to represent this on data on a HTML page, I'm doing the below
<div class="row" ng-repeat="person in persons">
<div class="col-xs-6">
{{person.personID}} - {{person.personName}}
</div>
<div class="col-xs-6">
<div class="row">
<div class="col-xs-12" ng-repeat="car in cars">
{{person.carID}} - {{getCarName(person.carID)}} -
{{person.relatedProperty1}} - {{person.relatedProperty2}}
</div>
<!-- Each Car-->
</div>
<!-- Array of Cars-->
</div>
<!-- Array of Cars Section -->
</div>
<!-- Person Row-->
Further, the data is being retrieved as below
modelInfo.controller('modelInfoController', function ($scope, $http, $filter) {
$http.get('http://localhost/person/123').
success(function(data) {
$scope.persons = data
}
$scope.getCarName = function(carID) {
$http.get('http://localhost/car/54545').
success(function(data) {
$scope.persons = data.carName
}
}
};
For some unknown reason, the script loops infinitely over the getCarName function. Please help me understand the issue. Also, please let me know if this is a good REST architecture.
You were missing a couple closing parenthesizes
modelInfo.controller('modelInfoController', function ($scope, $http, $filter) {
$http.get('http://localhost/person/123').success(
function(data) {
$scope.persons = data
}
); // <-- here, closing success function call
$scope.getCarName = function(carID) {
$http.get('http://localhost/car/54545').success(
function(data) {
$scope.persons = data.carName;
}
); // <-- here too
};
}); // <-- and here, closing the controller call
As for REST, it depends on how your backend server endpoints are defined
Although on the client side, you could define services for your resources, i.e. a wrapper for $http with REST methods (get, put, delete, update)

Resources