I seem to be repeating myself when building a detail class to display object data. Is there a way to *ngFor: for each attribute of the rug object, display the attribute's name, and then bind it to the object's value?
//rug-detail.component.ts
<div class="row">
<div class="col-md-3">Name:</div>
<div class="col-md-6">{{rug.name}}</div>
</div>
<div class="row">
<div class="col-md-3">ID:</div>
<div class="col-md-6">{{rug.id}}</div>
</div>
<div class="row">
<div class="col-md-3">Availability:</div>
<div class="col-md-6">{{rug.availability}}</div>
</div>
<div class="row">
<div class="col-md-3">Price:</div>
<div class="col-md-6">{{rug.price|currency:"USD":"symbol"}}</div>
//rug.ts
export interface Rug{
name: string;
id: number;
availability: String;
price: number;
}
The same question, for Ruby: Accessing a variable's name from an object
A hint:
rug = {
name: "Name",
id: 42,
availability: "in stock",
price: 123,
};
for (const key in rug) {
console.log(`${key}: ${rug[key]}`)
}
// OR
for (const key of Object.keys(rug)) {
console.log(`${key}: ${rug[key]}`)
}
One of the two must be usable in Angular's *ngFor
Related
i trying to display data with *ngFor, but for some reason this doesn't display any data, and any error.
I already tried alot of samples that i found in internet, none of those worked so i decide to ask here.
here is what i have:
ts file:
public querySuccess: any[];
this.userService.getMentions().subscribe(
(returnAPI) => {
this.querySuccess = returnAPI.data;
});
my html:
<div *ngIf="returnAPI">
<div *ngFor="let key of querySuccess">
<div>{{querySuccess.firstName}}</div>
</div>
</div>
<div *ngIf="!returnAPI">
<div>0 results found!</div>
</div>
the getMentions().subscribe() return this Json:
{
total: 3,
data:[
{userId: 0, firstName: "test", lastName: "xzy"},
{userId: 0, firstName: "john", lastName: "yeet"},
{userId: 0, firstName: "jamal", lastName: "abc"}]
}
You don't need that if condition to loop that ngFor.If its to show that no data error message use querySuccess because returnAPI does not seems to defined anywhere.
<div *ngIf="querySuccess">
<div *ngFor="let key of querySuccess">
<div>{{key.firstName}}</div>//key is single istance queryselector is full array.
</div>
</div>
<div *ngIf="!querySuccess">
<div>0 results found!</div>
</div>
you can try like this
<div *ngIf="returnAPI">
<div *ngFor="let key of querySuccess">
<div>{{key.firstName}}</div> <!-- key instead of querySuccess -->
</div>
</div>
Hi i would firstly recommend you put your code in a function like
ngOnInit() {
this.getAllQueries();
}
getAllQueries() {
this.userService.getMentions().subscribe(
(returnAPI) => {
this.querySuccess = returnAPI.data;
return this.querySuccess;
});
}
make sure you call this in the ngOninit function or your constructor
And i have a dynamic json coming from an API as below:
{123: "Mumbai", 456: "Bangalore", 789: "Chennai", 101: "Andhra",...}
I have below HTML code written in my template in which I am getting image-1, image-2 logos from my assets folder
<div class="row">
<div class="col-6" (click)="cityClick('Bangalore')">
<div class="img-1">
// my image-1 logo goes here
</div>
<div class="img-text">
Bangalore
</div>
</div>
<div class="col-6" col-6 (click)="cityClick('Mumbai')">
<div id="image_block" class="img-2">
// my image-2 logo goes here
</div>
<div id="text_block" class="img-text">
Mumbai
</div>
</div>
</div>
How to get the key of the json when i click on image and also display the text below the image from the corresponding key-value.
And when i click i should be able to pass the key and text inside the click event. Please help as i am new to Angular!
First convert this JSON into an JavaScript/TypeScript array like below:
var json = {123: "Mumbai", 456: "Bangalore", 789: "Chennai", 101: "Andhra" };
var jsonToBeUsed = [];
for (var type in json) {
item = {};
item.key = type;
item.value = json[type];
jsonToBeUsed.push(item);
}
This will result in data like below:
Now use NgFor in the template to bind array. (Refer this for NgFor)
<div class="row">
<div *ngFor="let item of array">
<div class="col-6" (click)="cityClick(item)">
<div class="img-1">
// my image-1 logo goes here
</div>
<div class="img-text">
{{item.value}}
</div>
</div>
</div>
</div>
We have passed the whole object in the click event. You can read any of the desired property from the object in click event handler which you will write in the component.
For your special requirement, you can use below markup:
<div class='row' *ngFor='let index of array; let i = index; let even = even'>
<div *ngIf="even" class='col-6' (click)="cityClick(array[i])">
<div class="img-1">
// my image-1 logo goes here
</div>
<div class="img-text">
{{array[i].value}}
</div>
</div>
<div *ngIf="!even" class='col-6' (click)="cityClick(array[i])">
<div class="img-1">
// my image-1 logo goes here
</div>
<div class="img-text">
{{array[i].value}}
</div>
</div>
</div>
Use this below function in your code:
getKeyByValue(object, value) {
return Object.keys(object).find(key => object[key] === value);
}
And use as
var dynamicJson = {123: "Mumbai", 456: "Bangalore", 789: "Chennai", 101: "Andhra"}
cityClick(value){
var key = this.getKeyByValue(this.dynamicJson, value);
console.log(key);
}
{123: "Mumbai", 456: "Bangalore", 789: "Chennai", 101: "Andhra",...}
Do you have influence on that JSON? This highly looks like a design issue for me. I assume those numbers are id's. I believe somethings like this should be better:
[{id: "123", name: "Mumbai"}, {id: "456", name: "Bangalore"}, {id: "789", name: "Chennai"}, {id: "101", name: "Andhra"},...}]
In that case you receive an array of cities, which could be an interface to parse to.
export interface City {
id: string;
name: string;
}
And you can easily render it in html by using *ngFor
<div *ngFor="let city of cities">
<!--do something with city.id and city.name-->
</div>
<div *ngFor let value of json |keyvalue > </div>
I am using an array of objects to populate info in a directive, but I do not know, when looping through that array, how to insert each object in the array into the "info" parameter of my directive.
Basically, the HTML template uses data passed to it in the info parameter, like so:
<directive info="{{angular object}}"></directive>
I know how to do this when I've hard-coded individual objects in the controller, like so:
$scope.object1 = {...values here...}
$scope.object2 = {...values here...}
etc.
For this I use:
<directive info="object1"></directive>
<directive info="object2"></directive>
But when I'm looping, I can't do that because I need to repeat the directive for each object in the array.
Here's what i've got
<div class="main" ng-controller="MainController">
<div class="container">
<div class="card" ng-repeat="app in apps">
<app-info info="{{app}}"></app-info> <!--HERE IS MY PROBLEM-->
</div>
</div>
</div>
Obviously I have no idea how or what to put as a value for the "info" parameter.
My MainController is as follows:
$scope.apps = [
{
icon: 'img/move.jpg',
title: 'MOVE',
developer: 'MOVE, Inc.',
price: 0.99
},
{
icon: 'img/gameboard.jpg',
title: 'Gameboard',
developer: 'Armando P.',
price: 1.99
},
{
icon: 'img/forecast.jpg',
title: 'Forecast',
developer: 'Forecast',
price: 1.99
},
{
icon: 'img/shutterbugg.jpg',
title: 'Shutterbugg',
developer: 'Chico Dusty',
price: 2.99
}];
The result is empty, meaning when I load the webpage, there is nothing there.
Just remove brackets. You were close.
<div class="main" ng-controller="MainController">
<div class="container">
<div class="card" ng-repeat="app in apps">
<app-info info="app"></app-info> <!--HERE IS NO PROBLEM-->
</div>
</div>
</div>
Trying to add a new object to an array and have it show up in an ng-repeat div. I add the object, look at the array in Chrome's dev tools and can see the new object in there, but the ng-repeat section just has a blank row. I've search throughout StackOverflow, implemented many solutions and still have this problem.
HTML:
<div ng-repeat="subItem in ec.mainItem.SubItems">
<div class="row">
<div class="col-md-12">
<div class="row">
<div class="col-md-3 h4">
<button class="btn-link">{{subItem.Name}}</button>
</div>
<div class="col-md-6">
{{subItem.Description}}
</div>
</div>
</div>
</div>
</div>
ItemCtrl.ts
module MainItemApp {
'use strict'
export class MainItemEntryCtrl implements IMainItemCtrl {
static $inject = ['$scope', '$routeParams', 'ItemSvc'];
public mainItem: MainItem; //this has an array on it named SubItems
public sub_item_name: string;
public sub_item_description: string;
public sub_item_date: Date;
public sub_item_start_date: Date;
public sub_item_end_date: Date;
public sub_item_descriptive_location: string;
public sub_item_short_location: string;
constructor($scope, $routeParams: IItemEntryRouteParams, itemSvc: ItemSvc) {
this.id= this.getId($routeParams.id);
if (this.id!= undefined) {
itemSvc.getMainItem(this.id).then(
(data) => this.mainItem = data);
}
}
addSubItem() {
var subItem = {
id: '',
name: this.sub_item_name,
itemDate: this.sub_item_date,
startDate: this.sub_item_start_date,
endDate: this.sub_item_end_date,
description: this.sub_item_description,
descriptiveLocation: this.sub_item_descriptive_location,
shortLocation: this.sub_item_short_location,
geoLat: '',
geoLong: '',
groupItems: []
};
this.mainItem.SubItems.push(subItem);
}
}
When I click a button, AddSubItem runs, the item gets created and after the push, I can hover over subItems and see the array has two objects, the one I loaded with and the one I pushed, but the HTML that's generated gives me this:
<div ng-repeat="subItem in ec.mainItem.SubItems">
<div class="row">
<div class="col-md-12">
<div class="row">
<div class="col-md-3 h4">
<button class="btn-link">Some Item</button>
</div>
<div class="col-md-6">
Some Description
</div>
</div>
</div>
</div>
</div>
<div ng-repeat="subItem in ec.mainItem.SubItems">
<div class="row">
<div class="col-md-12">
<div class="row">
<div class="col-md-3 h4">
<button class="btn-link"></button>
</div>
<div class="col-md-6">
</div>
</div>
</div>
</div>
</div>
Any ideas? Any help would be greatly appreciated!
Sorry, bad post, I figured it out (isn't it always like that, as soon as you make a fool of yourself and ask, you figure it out). My data was coming back from the API with capitalized property names (i.e. Name, Description) and I was adding an object where the names were lowercase (i.e. name, description) so of course there was nothing to show in the newly added row. So I synced up the names coming from my API with the names in the Typescript classes and everything is working now. So of course when I searched for the answer, I couldn't find it: no one posted "Hey dummy! Check the casing on your properties!"
So I think I will leave this up just in case someone else runs across the same problem and it sparks them to check their casing.
In my Angular app, I am using ng-repeat to cycle through all the items in a JSON object I have. So for example, for my JSON object:
$scope.animals =
{
horse: {
sound: "Nay",
legs: 4,
}
beaver: {
sound: "thwack",
legs: 2
}
}
I want to cycle through to get a list consisting of Horse, Beaveri.e.
<div ng-repeat="(key, value) in animals">
<div class="niceBox">
<h1> {{key}} </h1>
</div>
</div>
but for each animal, I want to have a button that takes the whole object and adds it to a list of my favorite animals. Something like this:
<div ng-repeat="(key, value) in animals">
<div class="niceBox">
<h1> {{key}} </h1>
<div ng-click="addToFavorites(animal)">Add To Favorites</div>
</div>
</div>
The Trouble Is that I can't just pass animal as a parameter since I broke up the ng-repeat into (key, value) already.
How do I reassemble (key, value) so I could use the object as a whole?
Your question is misleading, because there's no original "object" you want to re-assemble - there's just property names and values. If you had a single object for the animal in the first place:
var animals = [{
name: 'horse',
sound: ...,
...
}, {
name: 'beaver',
...
}, ...];
there would be nothing to "re-assemble", you'd just use it:
<div ng-repeat="animal in animals">
{{animal.name}}
<button ng-click="addToFavorites(animal)">...</button>
</div>
Try by this this
<div ng-repeat="(key, value) in animals">
<div class="niceBox">
<h1> {{key}} </h1>
<div ng-click="addToFavorites(key, value)">Add To Favorites</div>
</div>
</div>
And in your controller
$scope.addToFavorites = function(key, value) {
$scope.animal = {};
animal[key] = value;
/** your code **/
}