Handle multiple item in single controller? AngularJS - javascript

I am relatively new to Angular JS. Currently I met a problem, lets say I have 1000 items in a list. In order to display the details about each item I will pass the items_id to generate html example(123.html). In this case, do I need 1000 controller to handle this kind of situation?
Controller
app.controller('item0001',function($scope,$http,$sce){
$scope.data = [];
$scope.details=[];
$http.get("https://api.com/test/product/0001").then(function(response){
var getData = response.data;
$scope.data.push(response.data);
$scope.bindHtml = $sce.trustAsHtml(getData.details);
for(var i = 0; i<getData.specification.length; i++){
$scope.details.push(getData.details[i]);
}
});
});
app.controller('item0002',function($scope,$http,$sce){
$scope.data = [];
$scope.details=[];
$http.get("https://api.com/test/product/0002").then(function(response){
var getData = response.data;
$scope.data.push(response.data);
$scope.bindHtml = $sce.trustAsHtml(getData.details);
for(var i = 0; i<getData.specification.length; i++){
$scope.details.push(getData.details[i]);
}
});
});
View
<p>
View More
</p>

Use single controller and HTML.
Bind the HTML with some ViewModel (a property on $scope)
From your controller place the call to fetch item details (I am assuming you have fetch these details on click of some button) using a service.
In success callback of your service update the view model. and angular using 2-way binding, will update the view with last item fetched.
Controller:
app.controller('ProductCtrl', function($scope, ProductService) {
var getProduct = function(productId) {
ProductService.getProduct(productId).then(function(response) {
$scope.productDetails = response.data;
})
};
});
Service:
app.factory('ProductService', function($http) {
return {
getProduct(productID) {
return $http({
method: 'GET',
url: "https://api.com/test/product/" + productID
});
};
}
});
HTML View:
<body ng-controller="ProductCtrl">
<div ng-init="getProduct(0001)">
<p>Name {{productDetails.name}}</p>
<p>ID {{productDetails.id}}</p>
<p>Description {{productDetails.description}}</p>
</div>
<button ng-click="getProduct(productDetails.id + 1)">Get Next Product</button>
</body>
I hope this gives you a basic idea of how to implement your requirement. Please elaborate your question so that I can provide a more specific solution.

Define a single view (html) and controller to handle this.. example below.
productDetails.html (view)
<div>
<span>{{productName}}</span>
</div>
productDetails.js (controller)
app.controller('productDetailsCtrl',function($scope,$http,$sce){
$scope.productName = "";
$http.get("https://api.com/test/product/0001").then(function(response){
var getData = response.data;
$scope.productName = getData.productName;
});
});

Related

angularjs: how to store the function returning value in one variable . based on ng-repeat

hi i am getting the intrestedid from ng-repeat , i want to call another service and store that data in one variable dynamically , because need send seperate api for getting images.
my html is look like this
<div class="" ng-repeat="item in items" >
<div ng-init="MyPic = getMyprofile(item.interestedTo)">
<img src="{{MyPic}}">
</div>
</div>
My controller is look like this.
$scope.getMyprofile = function(IntrstdId){
appServices.profile( IntrstdId, function(response){
$scope.meDetails = response.data;
})
return $scope.meDetails;
}
My services is look like this.
service.profile= function(userId, callback) {
path = serviceUrl + '/profile/'+ userId;
$http({
method: 'GET',
url: path
}).then(function(data) {
callback(data)
}, function(data) {});
}
but its getting undefined , any issues in this code.
I tried to resolve this by creating some abstract stub, that may be helpful to you. Please review and let me know if issue still arise
HTML
<div ng-repeat ="data_ in parentData track by $index">
<ul>
<li ng-repeat="result in data_.data track by $index" ng-init="counter=increaseCounter();">
<div ng-model="counter"></div>
</ul>
</div>
Controller
// It simply store variable value in scope.counter
$scope.counter = 0;
$scope.increaseCounter = function () {
var cnt = $scope.counter++;
return cnt;
};
//Another way is to call service while update variable vaule
$scope.counter = 0;
$scope.increaseCounter = function () {
var cnt = $scope.counter++;
AppService.updateValue(cnt);
return cnt;
};
$scope.getMyprofile = function(IntrstdId){
appServices.profile( IntrstdId, function(response){
$scope.meDetails = response.data;
})
return $scope.meDetails;
}
I think issue is this function. appService.profile is asyncronize method and before complete it function return $scope.meDetails;
my suggestion is to hardcore some value like in below and see the result. if it is working then you have to change the function accordingly.
$scope.meDetails ='some value';
return $scope.meDetails;
There are several best practice issue along with the async problem.
1.Avoid using ng-init unless you want to re-run the function when you reconstruct the element, for instance ng-if. It is more so when you use ng-repeat without track by, any changes in the data source would re-trigger all ng-init in the children.
Solution: Run them when you init the controller, or as soon as $scope.items is filled.
angular.forEach($scope.items, function(item) {
appServices.profile(item).then(function(data){
item.myPic = data;
});
});
<div class="" ng-repeat="item in items" >
<img src="{{item.myPic}}">
</div>
2.The correct way to wrap a function that returns promise (which $http is) is to return the function itself. You can research more on how to pass the resolved/rejected result around.
// not needed anymore, just to showcase
$scope.getMyprofile = function(IntrstdId){
return appServices.profile( IntrstdId );
}
// same goes with the service function
service.profile= function(userId) {
path = serviceUrl + '/profile/'+ userId;
return $http({
method: 'GET',
url: path
}).then(function(response) {
return response.data;
});
}

Javascript Assign New Field to object

I have a snippet of code here running in a node application
for( i=0; i < Equipment.length; i += 1 ) {
Equipment[i].NumberForSearch = Equipment[i].ClassPrefix + "-" + Equipment[i].UnitNumber;
console.log(Equipment[i].NumberForSearch);
}
console.log(Equipment[0]);
Equipment is an array of objects and I am trying to add a property to each object in that array called "NumberForSearch".
In my application the way we want to display unit numbers for equipment is "ClasssPrefix"-"UnitNumber". The reason I am wanting to join them here into one variable is that inside my angular application, I want the user to be able to type 12345-12345 inside of a search field which then filters out the Equipment. This doesnt work if I have {{ClassPrefix}}-{{UnitNumber}} for obvious reasons, angular doesnt know that the - even exists.
The problem is that inside my for loop everything is checking out fine. Its logging just as its supposed to, so I figured it worked. When I checked the front end and changed it to display "NumberForSearch", nothing showed up.
I then added the logging statement outside the for loop to check just one of my objects to see if the field even existed and it doesnt. So my question is, why is this snippet not adding the "NumberForSearch" field in my object?
You have to make object with this field before setting to $scope's parameter.
Have a look at init() function.
After adding NumberForSearch field we defined array of objects to parameter in scope.
Of course ng-repeat will loop through it and render elements.
So we will add "| filter:query" to show only needed
<div ng-controller="EquipmentController">
<input type="text" ng-model="query.NumberForSearch" placeholder="search">
<ul>
<li ng-repeat="Item in Equipment | filter:query">{{Item.ClassPrefix}}-{{Item.UnitNumber}}</li>
</ul>
</div>
js part:
var App = angular.module('App', []);
App.controller('EquipmentController', function ($rootScope, $scope, $http, $filter) {
$scope.Equipment = [];
$scope.init = function() {
var request = $http({
method: 'get',
url: '/path/to/equipment/resource'
});
request.success(function (response) {
var Equipment = response.Equipment;
for(var i in Equipment) {
Equipment[i].NumberForSearch = Equipment[i].ClassPrefix + "-" + Equipment[i].UnitNumber;
}
$scope.Equipment = Equipment;
$scope.$apply();
});
}
$scope.init();
});
another way of filtering is to send search field to route, in another word we send query to server and it filters response on serverside.
<div ng-controller="EquipmentController">
<input type="text" ng-model="queryNumber" ng-change="searchByNumber()" placeholder="search">
<ul>
<li ng-repeat="Item in Equipment">{{Item.ClassPrefix}}-{{Item.UnitNumber}}</li>
</ul>
</div>
js part:
var App = angular.module('App', []);
App.controller('EquipmentController', function ($rootScope, $scope, $http, $filter) {
$scope.Equipment = [];
$scope.all = function() {
var request = $http({
method: 'get',
url: '/path/to/equipment/resource'
});
request.success(function (response) {
$scope.Equipment = response.Equipment;
$scope.$apply();
});
}
$scope.all();
$scope.searchByNumber = function() {
var request = $http({
method: 'get',
url: '/path/to/equipment/resource?number='+$scope.queryNumber
});
request.success(function (response) {
$scope.Equipment = response.Equipment;
$scope.$apply();
});
}
});

Ng-model with Cookie

I'm trying to take the first example from the angular.js homepage and adding in cookie support.
This is what I have so far: https://jsfiddle.net/y7dxa6n8/8/
It is:
<div ng-app="myApp">
<div ng-controller="MyController as mc">
<label>Name:</label>
<input type="text" ng-model="mc.user" placeholder="Enter a name here">
<hr>
<h1>Hello {{mc.user}}!</h1>
</div>
</div>
var myApp = angular.module('myApp', ['ngCookies']);
myApp.controller('MyController', [function($cookies) {
this.getCookieValue = function () {
$cookies.put('user', this.user);
return $cookies.get('user');
}
this.user = this.getCookieValue();
}]);
But it's not working, ive been trying to learn angular.
Thanks
I'd suggest you create a service as such in the app module:
app.service('shareDataService', ['$cookieStore', function ($cookieStore) {
var _setAppData = function (key, data) { //userId, userName) {
$cookieStore.put(key, data);
};
var _getAppData = function (key) {
var appData = $cookieStore.get(key);
return appData;
};
return {
setAppData: _setAppData,
getAppData: _getAppData
};
}]);
Inject the shareDataService in the controller to set and get cookie value
as:
//set
var userData = { 'userId': $scope.userId, 'userName': $scope.userName };
shareDataService.setAppData('userData', userData);
//get
var sharedUserData = shareDataService.getAppData('userData');
$scope.userId = sharedUserData.userId;
$scope.userName = sharedUserData.userName;
Working Fiddle: https://jsfiddle.net/y7dxa6n8/10/
I have used the cookie service between two controllers. Fill out the text box to see how it gets utilized.
ok, examined your code once again, and here is your answer
https://jsfiddle.net/wz3kgak3/
problem - wrong syntax: notice definition of controller, not using [] as second parameter
If you are using [] in controller, you must use it this way:
myApp.controller('MyController', ['$cookies', function($cookies) {
....
}]);
this "long" format is javascript uglyfier safe, when param $cookies will become a or b or so, and will be inaccessible as $cookies, so you are telling that controller: "first parameter in my function is cookies
problem: you are using angular 1.3.x, there is no method PUT or GET in $cookies, that methods are avalaible only in angular 1.4+, so you need to use it old way: $cookies.user = 'something'; and getter: var something = $cookies.user;
problem - you are not storing that cookie value, model is updated, but cookie is not automatically binded, so use $watch for watching changes in user and store it:
$watch('user', function(newValue) {
$cookies.user = newValues;
});
or do it via some event (click, submit or i dont know where)
EDIT: full working example with $scope
https://jsfiddle.net/mwcxv820/

Can't pass ID and call Controller from ajax or AngularJS

I have a table of objects, and I want to pass their ID on click, and without refresh populate a div or table, I've tried with AJAX and angular but can not pass ID.
If I fix the ID on a specific number it works.
In the View:
<script>
function CountryController($scope, $http) {
$http.get("/api/SportApi/GetCountry/").success(function (response) {
$scope.controllerFunction = function (value) {
console.log(value);
}
obj = JSON.parse(response);
$scope.country = angular.fromJson(obj);
});
}
</script>
<a class="item item-thumbnail-left" ng-href="#/api/SportApi/GetCountry/{{x.id}}" ng-click="CountryControler(x.id)">
click for countries
</a>
Could you try this:
function CountryController($scope, $http, id) {
console.log(id)
$http.get("/api/SportApi/GetCountry/").success(function (response) {
$scope.controllerFunction = function (value) {
console.log(value);
}
obj = JSON.parse(response);
$scope.country = angular.fromJson(obj);
});
}
On your view, you should have:
<a class="item item-thumbnail-left" href ng-click="CountryControler(x.id)">click for countries</a>
where href will stop the link from reloading the page and the ng-click will call a method on your controller.
In your controller, you should define that function on the scope variable:
var myApp = angular.module('myApp',[]);
myApp.controller('ExamleController', ['$scope', function($scope) {
$scope.CountryController = function(id) {
$http.get("/api/SportApi/GetCountry/" + id).success(function (response) {
$scope.controllerFunction = function (value) {
console.log(value);
}
obj = JSON.parse(response);
$scope.country = angular.fromJson(obj);
});
}
}]);
Verify that you have bootstrapped angular js (by defining the root element of your html with ng-app).
Verify that you have attached the controller class to your view (by defining the controller html element with ng-controller).
You should also verify that you are getting the right id on the view when calling "x.id".
$scope.controllerFunction seems unnecessary in this case.

Angularjs pass data in between services that exist on different pages

I have a simple book store example that I am working through for angularjs and I am trying to pass a book id from a home page into a service on an edit page so that the book details can be rendered. What I have happen is I can see the rest call being hit from my home' page with the correct book id being passed into the book service. However, I cannot seem to think of a way to have theBookCtrl` load that data when a different page invokes the rest service. The order I am expecting is:
1) User enters a book ID to edit
2) User presses Search button
3) book.html page is loaded
4) BookEdit service is invoked with ID from Steps 1 and 2
5) ng-model for book loads data.
Apologies in advance, there may be some errors as I was modifying this code from a different computer, so I couldn't copy/paste
code below:
home.html
<div ng-controller="HomeCtrl">
<div>
<label for="query">Book to edit</label>
<input id="query" ng-model ="editBook.query">
<button ng-click="loadBookById()">Search</button>
</div>
</div>
home.js:
var homeApp = angular.module('bookHome',['bookEdit']);
homeApp.controller('HomeCtrl',function($scope,$http,bookEditService)
{
$http.get('http://get/your/books/rest').success(function(data){
$scope.library = data;
});
$scope.editBook = {
query: '',
service:'bookEditService'
} ;
$scope.loadBookById = function()
{
$scope.$emit('loadBookById',{
query:$scope.editBook.query,
$service: $scope.editBook .service
}
$scope.$on('loadBookById', function(ev,search){
bookEditService.loadBook({
bookId: $scope.editBook.query
},
$scope.searchComplete,
$scope.errorSearching
);
});
$scope.searchComplete = function(results) {
$scope.results = results;
};
$scope.errorSearch= function(data,status,headers,config){
console.log(data);
// ...
};
}
book.html
<div ng-controller="BookCtrl" >
<div ng-model="details.title"></div>
<div ng-model="details.author"></div>
</div>
bookEdit.js
var bookEditApp = angular.module('bookEdit',[]);
bookEditApp.service('loadBook',function($http){
return{
loadBookById: function(params,success,error){
$http({
url: 'http://path/to/book/editing',
method: 'GET',
params:{bookId: params.bookId}).success(function(data,status,headers,config)
{
var results = data;
success(results || []);
}).error(function(){
error(arguments);
});
}
};
});
bookEditApp.controller('BookCtrl',function($scope){
$scope.details = {
title: "",
author: ""
};
});
An alternative that follows the order you are expecting is:
1) User enters book id and presses button
2) HomeCtrl routes to EditCtrl with the entered id as a route parameter (no need to use the book service yet):
app.controller('HomeCtrl', function ($scope, $location) {
$scope.editBook = function () {
$location.path('/edit/' + $scope.id);
};
});
3) EditCtrl is loaded, retrieves the route parameter and asks the book service for the correct book:
app.controller('EditCtrl', function EditCtrl($scope, $routeParams, bookService, $location) {
$scope.loading = true;
bookService.getBookById($routeParams.id)
.then(function (result) {
$scope.book = result;
$scope.loading = false;
});
4) When book is loaded the model ($scope.book) is populated and the html is updated
Here is a working example that hopefully will give some further guidance and ideas: http://plnkr.co/edit/fpxtAU?p=preview

Categories

Resources