/*factory method for getting particular customers order*/
factory.getCustomer = function(customerId) {
for(var i=0,len=customers.length ; i<len ; i++) {
if(customers[i].id === parseInt(customerId)){
return customer[i];
}
}
return {};
};
return factory();
/*Controller*/
myApp.controller('OrdersController',['$scope','$routeParams','customersFactory', function($scope,$routeParams,customersFactory) {
var customerId = $routeParams.customerId;
$scope.customer = null;
function init() {
$scope.customer = customersFactory.getCustomer(customerId);
}
init();
}]);
/*View*/
<div class="container">
<div class="row">
<div class="col-md-12">
<h2>{{customer.name}}'s Orders</h2>
<table class="table table-hover">
<tr>
<th>Product</th>
<th>Total</th>
</tr>
<tr ng-repeat="order in customer.orders">
<td>{{ order.product }}</td>
<td>{{ order.total | currency }}</td>
</tr>
</table>
</div>
</div>
</div>
/*JSON FILE*/
{
"id": "1",
"joined": "2000-12-2",
"name": "Wali",
"city": "Dubai",
"orderTotal": "9.0765",
"orders": [
{
"id": "1",
"product": "protein",
"total": "11.987"
}
]
},
{
"id": "2",
"joined": "2004-12-2",
"name": "Ali",
"city": "London",
"orderTotal": "20.0765",
"orders": [
{
"id": "2",
"product": "bcca",
"total": "2.3456"
},
{
"id": "3",
"product": "baseball",
"total": "4.3456"
}
]
},
{
"id": "3",
"joined": "1980-11-2",
"name": "Zen",
"city": "Australia",
"orderTotal": "6.500",
"orders": [
{
"id": "3",
"product": "chocolate",
"total": "6.4567"
}
]
}
I have made a customers table from which we can perform the CRUD functionality, but when I click to check the particular customer order it is redirecting me to the right view via routing but particular customers orders are not displaying.
can any one suggest a solution for this?
According to your JSON data, the ID is a String, but you are parsing it into an integer, and using ===, which will match only if the value and the type of the compared variables match.
You need to change the if statement, one option is:
if (parseInt(customers[i].id) === parseInt(customerId))
Another option will be:
if (customers[i].id == customerId)
And yet another option is using angular's $filter service.
You need to inject it into your factory, and than in order to get the client, you can use:
var customer = $filter('filter')(customers, {id: customerId.toString()}, true);
return customer.length === 1 ? customer[0] : null;
The toString part is only because your JSON data have ID as as string, and the third argument is set to true to prevent 'like' filter (default $filter behavior will return id 10 for example also if the customerId is 1).
Related
Here is my JSON array :
"user" : {
"id": 456,
"nickname": "xxx",
"pf": {
"id": 123,
"account": [
{
"accountid": 1494235749,
"status": "New",
"accountnbr": 12345,
"cyc": {
"cycid": 1494404053,
"active": true,
"status": "New",
"name": "QST192017",
},
},
{
"accountid": 1494403399,
"status": "New",
"accountnbr": 915177,
"cyc": {
"cycleid": 1494406299,
"active": true,
"status": "Closed",
"name": "QSL342014"
}
},
{
"accountid": 1494500399,
"status": "New",
"accountnbr": 90010,
}
]
},
}
And this is what I have in my template :
<tr *ngFor="let account of accounts">
<td>{{ account.accountnbr }}</td>
<td>{{ account.cyc.name}}</td>
</tr>
I tried to retrieve a list of all my accounts , and as you can see one of the account has no cyc, and shows an error , any idea how to replace absent JSON object by null in the list ?
PS : I'm using angular2
Thank you.
/K
use account.cyc?.name will solve your problem. when account doesn't have cyc, your template will just show blank without any error.
see documentation of safe-navigation-operator(?).
<tr *ngFor="let account of accounts">
<td>{{ account.accountnbr }}</td>
<td>{{ account.cyc?.name}}</td>
</tr>
This is as simple as using an *ngIf:
<div *ngFor="let acc of account">
<div *ngIf="!acc.cyc">NO CYC ON THIS ACCOUNT</div>
</div>
For this purpose an absent object is null/undefined.
You could also map over the object in your component and set it as null:
account.map(x =>{
if(!x.cyc){
x.cyc = null;
}
return x;
});
I have problem as in the topic. Using $parent in ng-model didn't help.
What I am trying to achieve is 2 clickable buttons to increase and decrease quantity field value by one and display summary (sum of each price*quantity) on the bottom of site.
var app = angular.module("mainApp", []);
app.controller("mainCtrl", function ($scope) {
$scope.list1 = [
{ "uniqueId": "1", "name": "cat1" },
{ "uniqueId": "2", "name": "cat2" }
];
$scope.list2 = [
{ "uniqueId": "1", "name": "prod1", "price": "10" },
{ "uniqueId": "2", "name": "prod2", "price": "20" },
{ "uniqueId": "3", "name": "prod3", "price": "30" }
];
// this one below doesn't work at all
// $scope.quantity[1] = 1;
$scope.inc = inc;
function inc(id) {
console.log(id); //works fine
// increase of exact quantity
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="mainApp">
<div ng-controller="mainCtrl">
<table ng-repeat="l1 in list1">
<tr>
<td>
{{l1.name}}
</td>
</tr>
<tr ng-repeat="l2 in list2">
<td>name: {{l2.name}},</td>
<td>price: {{l2.price}},</td>
<td>quantity wanted: <input ng-model="quantity[l2.uniqueId]"><button ng-click="inc(l2.uniqueId)" type="button">+</button></td>
</tr>
</table>
{{quantity}}<!-- sum of all quantities * prices -->
</div>
<div>
Keep in mind that there is mulitple way to solve this kind of problem, here is the grand line I see to do it and an example for each step:
Store your quantity somewhere and initialise it, for example in your product object, example in your controller:
{ "uniqueId": "1", "name": "prod1", "price": "10", quantity : 1 },
Create a function to increase and an other to decrease the quantity of a product by his id, example in your controller:
function increaseQuantity(id){
// Get your product in the list with a loop
// If the product exists
// Increase his quantity
}
function decreaseQuantity(id){
// Get your product in the list with a loop
// If the product exists
// Decrease his quantity
}
$scope.increaseQuantity = increaseQuantity;
$scope.decreaseQuantity = decreaseQuantity;
Call the right methods in your buttons, example in your view:
<td>
quantity wanted: {{l2.quantity}}
<button ng-click="increaseQuantity(l2.uniqueId)" type="button">+</button>
<button ng-click="decreaseQuantity(l2.uniqueId)" type="button">-</button>
</td>
I am trying to filter my data which I am getting from a HTTP GET endpoint by an array of values
filters = ['Full Time', 'LinkedIn', ...]
The general structure of the response I am getting back is an array of objects where each object can look like this:
{
"preferences": {
"jobType": {
"type": "Full Time"
}
},
"profile": {
"additionalinfo": {
"organization": [
{
"name": "Google"
},
{
"name": "LinkedIn"
}
],
"university": [
{
"name": "UC Berkeley",
"degrees": [ {"name": "Computer Engineering"}]
}
}
}
}
So if I filter by ["Google", "Full Time"], the above object should be included.
Is there a built in filter to handle this?
I am having trouble writing the custom filter to handle such a heavily nested object.
Any ideas on how to implement this?
You can use built in filter like this jsfiddle
var myApp = angular.module("myApp", []);
myApp.controller("myCtrl", function($scope) {
$scope.data = [{
"preferences": {
"jobType": {
"type": "Full Time"
}
},
"profile": {
"additionalinfo": {
"organization": [{
"name": "Google"
}, {
"name": "LinkedIn"
}],
"university": [{
"name": "UC Berkeley",
"degrees": [{
"name": "Computer Engineering"
}]
}]
}
}
}, {
"preferences": {
"jobType": {
"type": "Remote"
}
},
"profile": {
"additionalinfo": {
"organization": [{
"name": "Yandex"
}, {
"name": "LinkedIn"
}],
"university": [{
"name": "UC Berkeley",
"degrees": [{
"name": "Computer Engineering"
}]
}]
}
}
}];
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>
<body ng-app="myApp" ng-controller="myCtrl">
<h3>Jobs</h3>
<input ng-model="filterModelJobType" placeholder="filter jobType">
<input ng-model="filterModelJob" placeholder="filter job">
<table class="table table-striped table-bordered">
<tbody>
<tr ng-repeat="x in data|filter:{profile: {additionalinfo:{organization:{name:filterModelJob}}},preferences: {jobType:{type:filterModelJobType}}}">
<td>{{ $index + 1 | number }}</td>
<td class="text-center">{{ x.preferences.jobType.type }}</td>
<td class="text-left">
<div ng-repeat="org in x.profile.additionalinfo.organization">
<hr> {{org.name}}
</div>
</td>
</tr>
</tbody>
</table>
</body>
In the latest version of AngularJS
If there is nested object then
var foo = $filter('filter')($scope.welcome, {
additionalinfo: { name: 'google' }
});
Reference: GitHub issue
I have two scope variables in angularJS. One storing "all the subcategories" and other storing "categories and their respective subcategories".
$scope.Categories = [
{
"subcategories": [
{
"scname": "Sugar",
"scid": "5"
},
{
"scname": "Salt",
"scid": "6"
},
{
"scname": "Jaggery",
"scid": "7"
}
],
"name": "Salt and Sugar",
"id": "1",
"image": "/images/salt_sugar.png"
},
{
"subcategories": [
{
"scname": "Tea",
"scid": "8"
},
{
"scname": "Coffee",
"scid": "9"
},
{
"scname": "Tea Bags",
"scid": "162"
}
],
"name": "Tea and Coffee",
"id": "2",
"image": "/images/tea_and_coffee.png"
}
]
$scope.subcategories = [
{
"name": "Sugar",
"id": "5"
},
{
"name": "Salt",
"id": "6"
},
{
"name": "Jaggery",
"id": "7"
},
{
"name": "Tea",
"id": "8"
},
{
"name": "Coffee",
"id": "9"
},
{
"name": "Tea Bags",
"id": "162"
}
]
On selecting a category i want to display mapped and unmapped subcategories with that particular category. First one is very easy. How to filter second one? for example -
on selecting "Tea and Coffee" unmapped categories should be - Sugar, salt, Jaggery
on selecting "Salt and Sugar" unmapped categories should be - Tea, Coffee, Tea Bags
This is how I am listing mapped categories:
<TR align="center">
<TD>
<select ng-options="c as c.name for c in Categories|orderBy:'name' " ng-model="selectedCategory" size="10"> </select>
</TD>
<TD>
<select ng-options="sc as sc.scname for sc in selectedCategory.subcategories|orderBy:'scname' " ng-model="SelectedMappedSubCategory" size="10"> </select>
</TD>
<TD>
<select ng-options="sc as sc.name for sc in SubCategories | orderBy:'name' | ???????" ng-model="SelectedUnMappedSubCategory" size="10"> </select>
</TD>
</tr>
What logic should I use in-place if ?????????
If I understood correctly, why not just filter it?
| filter: {scname: SelectedUnMappedSubCategory.scname}
EDIT:
I can see that you edited the code you originally posted. I think you can achieve what you are trying to do, by this:
| filter: {id: SelectedUnMappedSubCategory.scid}
Create a customized filter:
sampleApp.filter('filterSubcategories', function() {
return function(input, filterkey) {
var filtered = [];
if (filterkey) {
for (var i = 0; i < input.length; ++i) {
var item = input[i];
var found = false;
for (var j = 0; j < filterkey.length; ++j) {
if (item.id == filterkey[j].scid) {
found = true;
break;
}
}
if (!found){
filtered.push(item);
}
}
}
return filtered;
};
});
and use this like:
<TD>
<select ng-options="sc as sc.name for sc in SubCategories | filterSubcategories:selectedCategory.subcategories | orderBy:'name'" ng-model="SelectedUnMappedSubCategory" size="10"> </select>
</TD>
I am creating a Grid Control in Angular JS. ( I don't want to use ng-grid, smart table, etc for some reason)
Plunkr URL : http://plnkr.co/edit/arkCZcfXTIsW7sFCxisn?p=preview
On top of the table generated, i have populated fields in the combobox so that user is allowed to search on specific columns
or as free search.
As I see From here :
https://docs.angularjs.org/api/ng/filter/filter
For free search, I have used the syntax as {$:Value} and for column based search, {ColName:Value} syntax
However, I am unable to get it to work when I bind the column names to combobox.
I do get static search to work Eg if I write {'Code':"1"}, this works. but if I take "Code" from a combobox, it doesnt work.
Need help on setting dynamic filter.
This one also does not seem to help.
angular filter with dynamic list of attributes to search
This is the HTML
<div ng-controller="MyGrid">
Search in Column
<select ng-model="FilterByColumn" >
<option value="$">All</option>
<option ng-repeat="hdr in headers | orderBy : hdr.displayOrder" ng-show="hdr.isVisible" value="{{hdr.name}}" >
{{hdr.caption}}
</option>
</select>
Value : <input type="text" ng-model="searchKeyword" />
<br />
Remove Sort
<table>
<thead>
<tr>
<th ng-repeat="hdr in headers | orderBy : hdr.displayOrder" ng-show="hdr.isVisible">
{{hdr.caption}}
</th>
</tr>
</thead>
<tbody>
<%--<tr ng-repeat="dataVal in data | filter: {FilterByColumn : searchKeyword} | orderBy:predicate:reverse "> **Does not work--%>**
<%--<tr ng-repeat="dataVal in data | filter: {$ : searchKeyword} | orderBy:predicate:reverse "> **This works--%>**
<tr ng-repeat="dataVal in data | filter: GetFilter (FilterByColumn, searchKeyword) | orderBy:predicate:reverse "> **<!-- Does not work -->**
<td ng-repeat="hdr in headers | orderBy : hdr.displayOrder" ng-show="hdr.isVisible">
{{dataVal[hdr.name]}}
</td>
</tr>
</tbody>
</table>
<pre>Sorting predicate = {{predicate}}; reverse = {{reverse}} ; SearchBy = {{FilterByColumn}} ; Search Key : {{searchKeyword}} </pre>
</div>
This is the JS :
'use strict';
var MyApp = angular.module('MyApp', []);
MyApp.controller('MyGrid', function ($scope) {
$scope.predicate = 'Code';
$scope.reverse = false;
$scope.FilterByColumn = '$';
$scope.headers = [
{
"name": "Code",
"caption": "Code",
"isVisible": true,
"displayOrder": 12
},
{
"name": "DispName",
"caption": "My Name",
"isVisible": true,
"displayOrder": 1
},
{
"name": "Locked",
"caption": "Islocked",
"isVisible": true,
"displayOrder": 2
}
];
$scope.data =
[{
"Code": "1",
"DispName": "abdul",
"Locked": "0"
},
{
"Code": "2",
"DispName": "Hemant",
"Locked": "0"
},
{
"Code": "3",
"DispName": "Rahul",
"Locked": "0"
},
{
"Code": "4",
"DispName": "Sandy",
"Locked": "0"
},
{
"Code": "5 ",
"DispName": "Nihal",
"Locked": "0"
},
{
"Code": "6",
"DispName": "Sachin",
"Locked": "0"
},
{
"Code": "7",
"DispName": "abdul f",
"Locked": "0"
},
{
"Code": "8",
"DispName": "abdul g",
"Locked": "0"
},
{
"Code": "9",
"DispName": "abdul h ",
"Locked": "0"
},
{
"Code": "10",
"DispName": "abdul i",
"Locked": "0"
}
];
$scope.getValue = function (obj, PropName) {
return obj[PropName];
};
$scope.SetSort = function (objName) {
//alert(objName);
$scope.predicate = objName;
$scope.reverse = !$scope.reverse;
};
$scope.GetFilter = function (srchCol, Srchval) {
//alert(srchCol);
//alert(Srchval);
if (srchCol == "") {
return { $: Srchval };
}
else {
return { srchCol: Srchval };
}
};
});
That is because when you write { srchCol: Srchval } - srcCol is the property name and is not substituted with the value in variable srcCol, try this syntax instead:
$scope.GetFilter = function (srchCol, Srchval) {
if (srchCol == "") {
return { $: Srchval };
}
else {
filter = {};
filter[srchCol] = Srchval;
return filter;
}
};