Angular dynamic array showing all results not just data under id - arrays

I am still trying to learn what seems to me like advanced Angular 5. The below code does enter the "id" number from the array into the url as expected, but when I go to model/1 it shows my all the objects from the array. I need to only see the object under id 1 and same for each object in the array. I have found so much conflicting information online, from mapping to queries that I'm not even sure where to being and everything I've tried has led to no better results. I have included all the code I'm working with.
I have an array of objects in my json file-
[
{
"id": 1,
"label": "Metal Man",
"sample": "/assets/img/metalman1.png",
"fab": "https://sketchfab.com/models/1b3cb7f8a77145bc8616075e9036b025/embed",
"img1": "/assets/img/metalman1.png",
"img2": "/assets/img/metalman2.png",
"img3": "/assets/img/metalman3.png"
},
{
"id": 2,
"label": "Magrot",
"sample": "/assets/img/magrot1.png",
"fab": "https://sketchfab.com/models/e20c8ade2f16452ca7f440aa84fc8e33/embed",
"img1": "/assets/img/magrot1.png",
"img2": "/assets/img/magrot2.png",
"img3": "/assets/img/magrot3.png"
},
{
"id": 3,
"label": "Baseball and Bat",
"sample": "/assets/img/ball1.png",
"fab": "https://sketchfab.com/models/781c60d3449b46f996a081ae36c20cce/embed",
"img1": "/assets/img/ball1.png",
"img2": "/assets/img/ball2.png",
"img3": "/assets/img/ball3.png"
}
]
My template for each of the above objects-
<div class="columnFlex mainBlock" *ngFor="let model of modelwork">
<div class="modelImagery">
<h1>{{ model.label }}</h1>
<iframe [src]='sanitizer.bypassSecurityTrustResourceUrl(model.fab)'
frameborder="1" allowvr allowfullscreen mozallowfullscreen="true"
webkitallowfullscreen="true" onmousewheel=""></iframe>
<img [src]="model.img1" />
<img [src]="model.img2" />
<img [src]="model.img3" />
</div></div>
And my Activatedroute set up-
import { Component, OnInit } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { CommonModule } from '#angular/common';
import { DomSanitizer } from '#angular/platform-browser';
import { ActivatedRoute } from '#angular/router';
import { Router } from '#angular/router';
#Component({
selector: 'app-model',
templateUrl: './model.component.html',
styleUrls: ['./model.component.css']
})
export class ModelComponent implements OnInit {
modelwork: any;
constructor( private route: ActivatedRoute, private router: Router, private http: HttpClient, public sanitizer: DomSanitizer ) {
this.sanitizer = sanitizer;
this.route.params.subscribe(params => {this.modelwork = params['id'];});
}
ngOnInit(): void {
this.http.get<any>('./assets/models.json').subscribe(
data => {
this.modelwork = data;
})
}
}
Any clarification on what I'm needing to do would be so appreciated! I'm trying to learn Angular in days and it is more complicated than I had expected. Thank you for taking the time to look at this!

I don't see anything advanced here. You simple have two asynchronous operations that both set the variable 'modelwork'. One of the operations sets modelwork to an integer and the other sets it to a json array. depending on which operation resolves first.
Edit
Looking at your comment, i see what you want to do. Here's an example:
chosenIndex: any;
modelwork: any;
constructor( private route: ActivatedRoute, private router: Router, private http: HttpClient, public sanitizer: DomSanitizer ) {
this.sanitizer = sanitizer;
}
ngOnInit(): void {
this.route.params.subscribe(params => {
this.chosenIndex = params['id'];
this.http.get<any>('./assets/models.json').subscribe(data => {
this.modelwork = data.filter(d => d['id'] == this.chosenIndex);
})
});
}
Modelwork will now contain an array of 1 object. The one object you want. You can alter this example to get whatever output you want.

Related

How to get data from observable?

Im trying to get some data from a request. I have an observable function that gives me the data inside of .subscribe, but whenever i try to get that data outside ( in a variable defined in the class) it will return me undefined and its quite annoying
Component.ts:
import { ProjectService } from '../services/project.service';
#Component({
selector: 'app-project-loader',
templateUrl: './project-loader.component.html',
styleUrls: ['./project-loader.component.css']
})
export class ProjectLoaderComponent implements OnInit {
projects:any;
constructor(private projectService: ProjectService) { }
ngOnInit(): void {
this.getProjects();
}
getProjects(){
this.projectService.getProjects().subscribe(data=>{
this.projects= data;
})
}
}
Component.html:
{{projects[0].id}}
The html is just for testing porpouses right now, so it has only 1 line. FYI the data returned in the observable function is an json array.
Array Example:
{
"id": "REDACTED",
"projectName": "REDACTED",
"projectId": "REDACTED"
},
{
"id": "REDACTED",
"projectName": "REDACTED",
"projectId": "REDACTED"
}
]
(Redacted are strings from a private db :P)
I solved it myself. I just had to use a *ngFor to encapsulate the projects like this:
<div *ngFor=" let project of projects">
<button class="list-group-item list-group-item-action" (click)="openProject(project.id)" >{{project.projectName}}</button>
</div>

ERROR TypeError: Cannot read property 'serviceId' of undefined

Iam using nested json as input to Angular 6 where below is what my json structure looks like:
{"contractId":1,"contractName":"Temp","contractServiceList":[{"id":1,"serviceId":{"serviceId":1,"serviceName":"Emergency Room"},"providerTier":"Tier 1","coinsurance":100.0,"copay":10.0,"penaltyApplies":"Y","penaltyRule":"Non Emergency ER Use","penaltyType":"Dollar Amount","penaltyValue":300.0,"deductibleApplies":"Y"}]}
In component.ts, my code is:
export class AppComponent implements OnInit {
services: Service;
serviceId: ServiceId[];
contract: Contract[];
constructor(private formBuilder: FormBuilder, private router: Router, private contractService: ContractService) { }
addForm: FormGroup;
ngOnInit() {
this.serviceId = [
{serviceId: '1', serviceName: 'Emergency Room'},
{serviceId: '2', serviceName: 'OP Radiology'}
];
component.html :
<div class="form-group col-xs-6">
<label for="serviceName">Category Of Services:</label>
<select id ="serviceName" formControlName="serviceName" name="serviceName" class="form-control">
<option *ngFor="let serv of serviceId" [value]="serv.serviceId">{{serv.serviceName}}</option>
</select>
</div>
I am submitting all the values in the form as (ngSubmit)="onSubmit" and subscribing it as below:
onSubmit() {
this.contractService.saveContract(this.addForm.value)
.subscribe( data => {
alert('Contract created successfully');
});
}
Not sure why it's not able to take serviceId value. Any help is appreciable!!

PrimeNG multiselect not binding in Model Driven form when pulling "typed" data from server

I am using PrimeNG Multiselect in a reactive Angular form.
I can see the array of values coming back from the server through the chrome dev tool, but I cant figure out how to get it to bind to the multi select.
module is imported in the component and the app module:
import { MultiSelectModule } from 'primeng/multiselect';
template:
<p-multiSelect [options]="activities" [optionLabel]="ActivityName" [panelStyle]="{minWidth: '300px'}" [showHeader]="true" formControlName="selectedActivities"></p-multiSelect>
Class:
export class ChemicalEditComponent implements OnInit {
activities: ActivityType[];
selectedActivities: ActivityType[];
constructor(
private _chemicalService: ChemicalService,
private fb: FormBuilder
) {
this.getActivities();
this.getSelectedActivities();
this.createForm();
}
ngOnInit() {
this.getChemical();
}
getActivities(): void {
this._chemicalService.getActivities().subscribe(result => this.activities = result);
}
getSelectedActivities(): void {
this._chemicalService.getActivitiesByChemical(this.chemicalId).subscribe(result => this.selectedActivities = result);
}
createForm() {
this.chemicalForm = this.fb.group({
brandName: '',
commonName: '',
formulation: '',
selectedActivities: ''
});
}
rebuildForm() {
this.chemicalForm.reset({
brandName: this.chemical.BrandName,
commonName: this.chemical.CommonName,
formulation: this.chemical.Formulation,
selectedActivities: this.selectedActivities
});
}
The json returned from the server looks like this:
0:{ActivityTypeId: 61, ActivityName: "Driving"}
1:{ActivityTypeId: 62, ActivityName: "Strolling"}
I'm seeing all the examples use "label" and "value" but mine is typed from the server. I'm assuming the problem is I need to specify what is the label & value, so I added the [optionLabel] tag but that didnt help.

NgFor only supports binding to Iterables such as Arrays while using array to create a dropdown selection

I am getting the below error while running the application:
ERROR Error: Cannot find a differ supporting object '[object Object]' of type 'subLandscape'. NgFor only supports binding to Iterables such as Arrays.
The subLandscape variable I am referring to in the HTML is an array but it throws an error while using it with "ngFor"
HTML:
<div class="form-group" [class.has-error]="subLandscape.invalid && subLandscape.touched">
<strong>Sub Landscape</strong>
<br>
<p>Please choose from one of the Sub Landscape options. Sub Landscape options are for reporting only.</p>
<label class="control-label">SubLandscape:</label>
<mat-select #subLandscape="ngModel" type="text" class="form-control" name="subLandscape" [ngModel]="model.subLandscape">
<mat-option *ngFor="let item of subLandscape">
{{ item }}
</mat-option>
</mat-select>
<div *ngIf="subLandscape.invalid && subLandscape.touched" class="alert alert-danger">
Select the Sub Landscape from the provided list.
</div>
</div>
Model:
export class SModel {
constructor (
public description: string,
public reasons: string,
public projectName: string,
public subLandscape: string,
public centerdata: string,
public nom: number,
public size: string,
public dbgh: string
) {
}
}
Component:
import { Component, OnInit } from '#angular/core';
import { Standalone } from '../standalone';
import { StandaloneModel } from '../models/standalone.model';
import {MatTableModule, MatTableDataSource} from '#angular/material/table';
#Component({
selector: 'app-standalone-form',
templateUrl: './standalone-form.component.html',
styleUrls: ['./standalone-form.component.css']
})
export class StandaloneFormComponent {
public project: string[] = ['', 'appdev', 'apptest', 'appqa'];
public subLandscape: string[] = ['DEV', 'Testing', 'QA', 'UAT'];
public dataCenter: string[] = ['PDC', 'SDC'];
public model = new SModel('', '', '', '', '', 0, '', '');
}
Probably because it is unable to differentiate between subLandscape from
#subLandscape="ngModel" and the component property array public subLandscape: string[] = ['DEV', 'Testing', 'QA', 'UAT'];. Change the name of either should solve the problem

Angular 2 not showing output on screen

Since I have begin to learn Angular 2 , I am following the basic concepts well. But when I tried running the below program, I don't get the values which is statically set in the code.
import { Component,Input } from '#angular/core';
export class Hero {
id: number;
name: string;
}
hero: Hero = {
id: 1,
name: 'Windstorm'
};
#Component({
selector: 'my-app',
template: '<h1>{{title}}</h1><h2>{{hero.name}} details!</h2><div><label>id: </label>{{hero.id}}</div><div><label>name: </label>{{hero.name}}</div>'
})
export class AppComponent {
title = 'Tour of Heroes';
hero = 'Windstorm';
}
Can someone please point out where I am wrong, also can someone show how to debug the Angular code so that I can learn the framework well and try complex things out by self-learning and solve out basic issues by myself?
The output which I got
This should work
#Component({
selector: 'my-app',
template: '<h1>{{title}}</h1><h2>{{hero.name}} details!</h2><div><label>id: </label>{{hero.id}}</div><div><label>name: </label>{{hero.name}}</div>'
})
export class AppComponent {
title = 'Tour of Heroes';
hero: Hero = {
id: 1,
name: 'Windstorm'
};
}
With hero = 'Windowstorm'; {{hero.name}} is invalid because hero doesn't have a name property.
I'm sure your browser console show an error message. Please add such errors to future questions.

Resources