I use Angular Cli6, angularfire2 and firebase. I want to create a timeline with GoogleChart.
//GoogleChart.service
declare var google: any;
export class GoogleChartsBaseService
{
constructor() { google.charts.load('current', {'packages':["timeline"]}); }
protected buildChart(data: any[], chartFunc: any, options: any) : void {
var func = (chartFunc, options) =>
{
var datatable = google.visualization.arrayToDataTable(data);
chartFunc().draw(datatable, options);
};
var callback = () => func(chartFunc, options);
google.charts.setOnLoadCallback(callback);
}
}
TimelineChart.service
import { GoogleChartsBaseService } from './google-charts-base.service';
import { Injectable } from '#angular/core';
import { GanttChartConfig } from './../models/GanttChartConfig.model';
declare var google: any;
#Injectable()
export class GoogleGanttChartService extends GoogleChartsBaseService {
constructor() { super(); }
public BuildPieChart(elementId: string, data: any[], config: GanttChartConfig) : void {
var chartFunc = () => { return new google.visualization.Timeline(document.getElementById(elementId)); };
var options = {
traitement: config.traitement,
datedebut: config.datedebut,
datefin: config.datefin,
};
this.buildChart(data, chartFunc, options);
}
}
Timeline.html
<div id="{{elementId}}" ></div>
Timeline.ts
import { Component, Input, OnInit } from '#angular/core';
import { GoogleGanttChartService } from './../../services/google-gantt-chart.service';
import { GanttChartConfig } from './../../models/GanttChartConfig.model';
declare var google: any;
#Component({
selector: 'app-gantt',
templateUrl: './gantt.component.html',
styleUrls: ['./gantt.component.scss']
})
export class GanttComponent implements OnInit {
#Input() data: any[];
#Input() config: GanttChartConfig;
#Input() elementId: string;
constructor(private _ganttChartService: GoogleGanttChartService) {}
ngOnInit(): void {
this._ganttChartService.BuildPieChart(this.elementId, this.data, this.config);
}
}
And the component to display the graph :
Component.html
<div class="full"><app-gantt [data]="data1" [config]="config1" [elementId]="elementId1"></app-gantt></div>
Component.ts
import { Component, OnInit, Inject } from '#angular/core';
import { Patient } from '../models/patient.model';
import { Diagnostic } from '../models/diagnostic.model';
import { ActivatedRoute, Router } from '#angular/router';
import { PatientsService } from '../services/patients.service';
import { DiagnosticsService } from '../services/diagnostics.service';
import { PPSsService } from '../services/ppss.service';
import { AngularFireDatabase, AngularFireList, AngularFireObject, AngularFireAction } from 'angularfire2/database';
import { Location } from '#angular/common';
import { Observable } from 'rxjs/Observable';
import { GanttChartConfig } from './../models/GanttChartConfig.model';
import { PPS } from '../models/pps.model';
import {MAT_MOMENT_DATE_FORMATS, MomentDateAdapter} from '#angular/material-moment-adapter';
import {DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE} from '#angular/material/core';
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA,MatDatepickerModule, MatFormFieldModule,} from '#angular/material';
import { FormControl, FormControlName, FormBuilder, FormGroup, Validators, ReactiveFormsModule, FormsModule } from '#angular/forms';
import { startWith } from 'rxjs/operators/startWith';
import { map, filter, catchError, mergeMap } from 'rxjs/operators';
#Component({
selector: 'app-pps',
templateUrl: './pps.component.html',
styleUrls: ['./pps.component.scss']
})
export class PpsComponent implements OnInit {
patientid: string;
patientToDisplay;
ppssToDisplay;
data1: any[];
config1: GanttChartConfig;
elementId1: string;
constructor(
private route: ActivatedRoute,
private location: Location,
private patientsService: PatientsService,
private diagnosticsService: DiagnosticsService,
private ppssService: PPSsService,
private router: Router,
public dialog: MatDialog,
){ }
ngOnInit() {
this.route.params.forEach((urlParameters) => {
this.patientid = urlParameters['id'];});
this.patientToDisplay =
this.patientsService.getSinglePatient(this.patientid);
this.ppssToDisplay = this.ppssService.getPPSByPatientid(this.patientid);
this.data1 = [[ 'traitement','start', 'end'],
[ 'Chirurgie', new Date(2017, 3, 29), new Date(2017, 3, 30)],
[ 'Chimiothérapie', new Date(2017, 2, 4), new Date(2018, 2, 4)],
[ 'Radiothérapie', new Date(2017, 2, 4), new Date(2018, 2, 4)]];
this.config1 = new GanttChartConfig( '',new Date (),new Date ());
this.elementId1 = 'myGanttChart';
Now i can display my graph easily with data write in my component
but my data are stocked in firebase like that :
I display the data with an observable from angularfire2
DATA.Service.TS
getPPSByPatientid(Patientid: string){
return this.database.list('/ppss', ref => ref.orderByChild("Patientid").equalTo(Patientid)).valueChanges();
}
I try this in my component .ts in order to have the good array for this.data1 but witout succes
Console.log(this.data1) send an array of undefined
let interestingFields = [ 'treatement','dateA', 'dateB'];
this.ppssToDisplay.subscribe(obj => {
this.data1 = [
interestingFields,
interestingFields.map(field => obj[field]),
];
console.log(this.data1);
});
Error:
core.js:1598 ERROR Error: Uncaught (in promise): Error: Not an array Error: Not an array
I wanted to put all of my code so you could have complete visualization of what I want to do.
My question is: Have I chosen the right solution or should I use a loop in my template to populate the chart?
And could someone show me the voice so I can sleep again (5 days lol)
It seems you have gotten the right solution. There is just one problem when getting your data to data1.
For the retrieved data to match the pattern on your data written in hard, you have to loop through it from the perspective of the retrieved data:
this.ppssToDisplay.subscribe(ppsList => {
this.data1 = [
interestingFields,
...ppsList.map(pps => interestingFields.map(field => pps[field]))
];
});
And there you go. That should solve your problem.
Related
I am working on an e-commerce app who's front-end is made in Angular 13.
I use a service to handle the products coming from an API. I run into a problem while ring to display the product details.
See Stackblitz demo HERE.
In app\services\product.service.ts I have:
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs';
import { HttpClient } from '#angular/common/http';
import { Product, ProductResponse } from '../models/product';
#Injectable({
providedIn: 'root'
})
export class ProductService {
products: Product[] = [];
apiURL: string = 'https://dummyjson.com';
constructor(private http: HttpClient) {}
// Product List
public getProducts(): Observable<ProductResponse>{
return this.http.get<ProductResponse>(`${this.apiURL}/products`);
}
// Product Details (single product)
public getProductDetails(id: Number): Observable<ProductResponse>{
return this.http.get<ProductResponse>(`${this.apiURL}/products/${id}`);
}
}
In app\app.module.ts:
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { CommonModule } from '#angular/common';
import { HttpClientModule } from '#angular/common/http';
import { AppComponent } from './app.component';
import { Routes, RouterModule } from '#angular/router';
import { NavbarComponent } from './components/navbar/navbar.component';
import { FooterComponent } from './components/footer/footer.component';
import { SidebarComponent } from './components/sidebar/sidebar.component';
import { HomeComponent } from './components/home/home.component';
import { ProductItemComponent } from './components/product-item/product-item.component';
import { ProductsListComponent } from './components/products-list/products-list.component';
import { ProductsDetailsComponent } from './components/products-details/products-details.component';
const routes: Routes = [
{ path: '', component: HomeComponent},
{ path: 'products', component: ProductsListComponent},
{ path: 'products/show/:id', component: ProductsDetailsComponent},
];
#NgModule({
declarations: [
AppComponent,
NavbarComponent,
FooterComponent,
SidebarComponent,
ProductsListComponent,
ProductItemComponent ,
ProductsDetailsComponent
],
imports: [
CommonModule,
BrowserModule,
HttpClientModule,
RouterModule.forRoot(routes),
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
In app\models\product.ts:
export class Product {
id?: number;
title?: string;
description?: string;
price?: number;
discountPercentage?: number;
rating?: number;
stock?: number;
brand?: string;
category?: string;
thumbnail?: string;
}
export interface ProductResponse {
products: Product[];
total: number;
skip: number;
limit: number;
}
In app\components\products-details\products-details.component.ts I have:
import { Component, OnInit, InputDecorator, Input } from '#angular/core';
import { Router, ActivatedRoute } from '#angular/router';
import { Product, ProductResponse } from '../../models/product';
import { ProductService } from '../../services/product.service';
#Component({
selector: 'app-products-details',
templateUrl: './products-details.component.html',
styleUrls: ['./products-details.component.css']
})
export class ProductsDetailsComponent implements OnInit {
#Input() product!: Product;
productResponse: any;
constructor(private ProductService: ProductService, private Router: Router, private ActivatedRoute:ActivatedRoute) { }
ngOnInit(): void {
const id = Number(this.ActivatedRoute.snapshot.paramMap.get('id'));
this.ProductService.getProductDetails(id).subscribe((response) => (this.productResponse = response));
}
}
In app\components\products-details\products-details.component.html I have:
<h1>{{ product.title }}</h1>
The problem
When I access a product details route (for instance, http://localhost:4200/products/show/1), the page displays an empty <h1> tag and the Chrome console shows Cannot read properties of undefined (reading 'title').
Where is my mistake?
Unlike the https://dummyjson.com/products endpoint, the https://dummyjson.com/products/{id} returns a plain Product object, so:
// product.service.ts
public getProductDetails(id: Number): Observable<Product>{
return this.http.get<Product>(`${this.apiURL}/products/${id}`);
}
// products-details.component.ts
// the #Input decorator is wrong — the data is not passed to the component from outside
// but instead fetched inside of the component
#Input() product!: Product;
// productResponse: any — this field is unused and should be removed
ngOnInit(): void {
...
this.ProductService.getProductDetails(id).subscribe((product) => (this.product = product));
}
The #Input() property only works for external assignment of values.
The following will probably do what you want:
product: Product | undefined;
this.ProductService.getProductDetails(id).subscribe((response) => (this.product = response));
<h1>{{ product?.title }}</h1>
Furthermore I believe handling raw responses should happen in the service instead of the component, but that may be a matter of personal preference.
I develop an application in angular, And I want testing my application with files spec.
But when I launch the file spec I have an error
"TypeError: settings is null in http://localhost:9876/karma_webpack/vendor.js (line 163664)"
I start with angular so I have any idea to correct my problem
modal-result-training.component.spec.ts
import { ComponentFixture, TestBed } from '#angular/core/testing';
import { IAttempt } from '../../models/attempt.model';
import { ITraining } from '../../models/training.model';
import { ModalResultTrainingComponent } from './modal-result-training.component';
import { OpinionsService } from 'app/feature/elearning-training/services/opinions.service';
import { EntityService } from '#core/services/entity.service';
import { FireModule } from '../../../../#core/fire/fire/fire.module';
import { UserService } from '#core/services/user.service';
import { NbAclService } from '#nebular/security';
import { NbAuthModule } from '#nebular/auth';
import { NbDialogModule, NbThemeModule } from '#nebular/theme';
import { Router, RouterModule } from '#angular/router';
import { DialogService } from '#core/services/dialog.service';
const training = {
id: 'ZGtz6yrEemCNTo5KAytu',
refProject: 'JGvD1faO8L2vWb66BQ87',
publicationDate: new Date(),
version: 1,
name: 'My project',
groups: [],
category: '',
description: '',
minimalScore: 80,
previewPNG: '',
level: 5,
gain: 5,
fromDate: new Date(),
toDate: new Date(),
totalSlides: 20,
stars: 3,
averageStars: 4,
comments: 15,
groupsHistoric: [],
} as ITraining;
const trainingResults = {
id: 'ZDqzqg',
version: 1,
trainingID: 'xSOvDC6vpZTzVqXy5owQ',
userID: 'qdZDZDqg',
groupsIDs: [],
date: new Date(),
time: 10,
score: 10,
validated: true,
finished: true,
currentStep: 4,
} as IAttempt;
fdescribe('ModalResultTrainingComponent', () => {
let component: ModalResultTrainingComponent;
let fixture: ComponentFixture<ModalResultTrainingComponent>;
let opinionsService: OpinionsService;
let dialogService: DialogService;
let userService: UserService;
let router: Router;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ModalResultTrainingComponent],
providers: [EntityService, OpinionsService, UserService, NbAclService],
imports: [FireModule, RouterModule.forRoot([]), NbThemeModule.forRoot(), NbDialogModule.forRoot(), NbAuthModule.forRoot()],
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ModalResultTrainingComponent);
component = fixture.componentInstance;
opinionsService = TestBed.inject(OpinionsService);
userService = TestBed.inject(UserService);
dialogService = TestBed.inject(DialogService);
router = TestBed.inject(Router);
component.training = training;
component.results = trainingResults;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
modal-result-training.component.ts
the begin of modal
import { Component, Input, OnInit } from '#angular/core';
import { FormBuilder, FormGroup, Validators } from '#angular/forms';
import { Router } from '#angular/router';
import { IOpinion } from '#core/models/opinion.model';
import { IUser } from '#core/models/user.model';
import { DialogService } from '#core/services/dialog.service';
import { UserService } from '#core/services/user.service';
import { NbDialogRef, NbGlobalPhysicalPosition, NbToastrService } from '#nebular/theme';
import { TranslateService } from '#ngx-translate/core';
import { OpinionsService } from 'app/feature/elearning-training/services/opinions.service';
import { cleanObject } from 'app/shared/utils';
import { first, switchMap } from 'rxjs/operators';
import { IAttempt } from '../../models/attempt.model';
import { ITraining } from '../../models/training.model';
/**
* A modal to displays the training results when it's complete.
*
* #export
* #class ResultTrainingComponent
* #implements {OnInit}
*/
#Component({
selector: 'ngx-modal-result-training',
templateUrl: './modal-result-training.component.html',
styleUrls: ['./modal-result-training.component.scss'],
})
export class ModalResultTrainingComponent implements OnInit {
#Input() results: IAttempt;
#Input() training: ITraining;
public validated = false;
public opinionForm: FormGroup;
public selectedStars = 0;
public hasAlreadyComment = true;
public percentageScore: number;
constructor(
private opinionsService: OpinionsService,
private userService: UserService,
private ref: NbDialogRef<ModalResultTrainingComponent>,
private router: Router,
private toastrService: NbToastrService,
private translateService: TranslateService,
private dialogService: DialogService
) {}
Thanks for help
I'm trying to get the data in my schedule subcollection so i can display it in my html template.
What I got so far is in my getScheduleList method in schedule.service.ts. it's seem I'm only getting metadata no matter what i try to do.
I've tried using: https://github.com/angular/angularfire for documentation because firebases own is kinda lacking.
schedule.service.ts
import {Injectable} from '#angular/core';
import {AngularFirestore} from '#angular/fire/firestore';
import {Schedule} from '../../model/schedule';
import {map} from 'rxjs/operators';
import {AuthService} from '../../auth/auth.service';
#Injectable({
providedIn: 'root'
})
export class ScheduleService {
constructor(public fireService: AngularFirestore, private authService: AuthService) {
}
getScheduleList() {
this.fireService.collection<any>('companies').snapshotChanges().pipe(map(actions => {
return actions.map(a => {
const data = a.payload.doc.data();
const id = a.payload.doc.id;
if (data.UID === this.authService.currentUserId) {
console.log(id);
this.fireService.collection(`companies/${id}/schedules`).snapshotChanges().subscribe(result => {
console.log('test', result);
});
}
});
})).subscribe();
}
}
schedule.component.ts
import {Component, OnInit} from '#angular/core';
import {NgbModal, NgbDateStruct, NgbCalendar, NgbModalConfig} from '#ng-bootstrap/ng-bootstrap';
import {NgForm} from '#angular/forms';
import {Schedule, ScheduleInterface} from '../../model/schedule';
import {ScheduleService} from '../../service/schedule/schedule.service';
import {ActivatedRoute} from '#angular/router';
#Component({
selector: 'app-schedule',
templateUrl: './schedule.component.html',
styleUrls: ['./schedule.component.css'],
})
export class ScheduleComponent implements OnInit {
dateModel: NgbDateStruct; // Holds the date structure day/month/year format
date: { year: number, month: number }; // Is for the datepicker month and year selector
schedule: ScheduleInterface; // schedule object uses interface from schedule models
scheduleList: ScheduleInterface[];
constructor(private config: NgbModalConfig,
private modalService: NgbModal,
private calendar: NgbCalendar,
private serviceSchedule: ScheduleService) {
// Customize default values of modals used by this component tree
config.backdrop = 'static';
config.keyboard = false;
}
// Initialises the schedule object with default values
ngOnInit(): void {
// this.schedule = new Schedule('', 'default', '10', '00:00');
this.schedule = new Schedule('', 'default', '2020', '00:00');
this.getScheduleList();
}
// Opens modal window
open(content) {
this.modalService.open(content);
}
// Gives to current day in the datepicker
selectToday() {
this.dateModel = this.calendar.getToday();
}
// Creates new task for the schedule
createSchedule(schedulecontent: NgForm) {
console.log(schedulecontent.value);
if (schedulecontent.valid) {
this.serviceSchedule.createSchedule(schedulecontent.value);
}
}
getScheduleList() {
const test = this.serviceSchedule.getScheduleList();
// console.log(test);
}
}
firebase collection
This is almost certainly not doing what you expect:
this.fireService.collection('companies/{id}/schedules')
If you want to use the value of id inside the string here, you should express it like this:
this.fireService.collection(`companies/${id}/schedules`)
Note the backtick quotes and dollar sign. This is JavaScript's way of doing string interpolation with template literals.
Hello so my problem is that I am trying to make a shared-service because I need an array in an other component. It seems like the "sender" class is working also as the service class itself. Just the "reciever" class isn't getting any data through the description. What do I need to change here to get it working?
Service:
import { Injectable } from "#angular/core";
import { Observable, Subject } from 'rxjs';
import { Note } from '../note/note-data';
#Injectable()
export class DataService {
exchangeData$: Observable<Note[]>
private dataSubject = new Subject<Note[]>()
constructor() {
this.exchangeData$ = this.dataSubject.asObservable()
}
exchangeData(data) {
console.log(data)
this.dataSubject.next(data)
}
}
Sender Class:
import { Component, OnInit } from '#angular/core';
import { NoteComponent } from 'src/app/note/note-component';
import { Note } from 'src/app/note/note-data';
import { Content } from '#angular/compiler/src/render3/r3_ast';
import { ContentSearcher } from './searcher/ContentSearcher';
import { DataService } from './ChangeDataService/DataService';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'noteApp';
public notes: Note[] = [
new Note("example title 1", "blablablalblalalblablabla", new Date(5000), new Date(5000)),
new Note("example title 2", "example description 2", new Date(5000), new Date(5000)),
new Note("example title 3", "example description 3 noch mehr blablalblalbla", new Date(5000), new Date(5000))
]
public constructor(private dataService:DataService) {
this.dataService.exchangeData(this.notes)
}
deleteNote(note: Note) {
var index = this.notes.indexOf(note, 0);
this.notes.splice(index, 1);
}
Reciever class:
import { Component, OnDestroy } from "#angular/core";
import { ContentSearcher } from './ContentSearcher';
import { Note } from '../note/note-data';
import { DataService } from '../ChangeDataService/DataService';
import { Subscription } from 'rxjs';
#Component({
selector: 'content-searcher',
templateUrl: './content.searcher.html',
styleUrls: ['./content.searcher.css']
})
export class ContentSearcherComponent implements OnDestroy {
public notes: Note[] = []
private subscription:Subscription
public constructor(private dataService: DataService) {
console.log("notes (constructor before init): "+this.notes)
this.subscription = this.dataService.exchangeData$.subscribe((data) => {
this.notes = data
console.log("notes in content.searcher (CONSTRUCTOR): "+this.notes)
})
console.log("subscription: "+this.subscription)
}
searcher: ContentSearcher = new ContentSearcher()
matchingNotes: Note[]
onKey(event) {
console.log("notes in content.searcher: "+this.notes)
const inputValue = event.target.value
if (this.notes != null) {
this.matchingNotes = this.searcher.searchContent(inputValue, this.notes)
}
}
getMatchingNotes(): Note[] {
return this.matchingNotes
}
ngOnDestroy() {
this.subscription.unsubscribe()
}
}
Need bit help in the Angular any version(2,3,4,5), I am trying from last 2 weeks. Any help would be appreciated.
Apologies, due to big code I am not able to add it in Plunker or JSfiddle.
My workflow goes like this
1 - load the metadata.json
2 - read the first value from the metadata.json
3 - load the first json from folder in APP_INITIALIZER
4 - Populate all the values from metadata.json in dropdown
5 - whenever dropdown value changed load the relaevant json and get the objects display in the UI
I have 3 components
Navigation.component (Dropdown change is triggering here)
dashboard.component (data will be changed based on dropdown content)
programmer.component (data will be changed based on dropdown content)
Whenever Dropdown change event is triggered I want to load the data from json.
metadata.json
[
{
"name": "Q_1090",
"value": "project_q_1090.json"
},
{
"name": "Q_1234",
"value": "project_q_1234.json"
},
{
"name": "Q_1528",
"value": "project_q_1528.json"
}
]
app.config.ts
import { Injectable } from '#angular/core';
import { Http } from "#angular/http";
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import { Observable } from 'rxjs/Observable';
#Injectable()
export class AppConfig {
config: any;
user: any;
objects: any;
fileName: any;
constructor(private http: Http) {
console.log('ConfigService called.')
}
load(projectName) {
return new Promise((resolve) => {
/** This method: Loads "host_configuration.json" to get the current working environment. */
this.http.get('./assets/host_configuration.json').map(res => res.json())
.subscribe(config => {
console.log('Configuration loaded');
this.config = config;
/** This method: Loads all the objects from json */
let getSummaryParameters: any = null;
getSummaryParameters = this.http.get('./assets/json/' + projectName);
if (getSummaryParameters) {
getSummaryParameters
.map(res => res.json())
.subscribe((response) => {
this.objects = response;
return resolve(true);
});
} else {
return resolve(true);
}
});
});
}
loadMetadata() {
return new Promise((resolve) => {
//reading metadata.json
this.http.get('./assets/metadata.json').map(res => res.json())
.subscribe(fileName => {
console.log('metadata loaded');
this.fileName = fileName;
return resolve(true);
});
});
}
}
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule, APP_INITIALIZER } from '#angular/core';
import { FormsModule } from '#angular/forms';
import { RouterModule } from '#angular/router';
import { HttpClientModule } from '#angular/common/http';
import { HttpModule, JsonpModule } from '#angular/http';
import { AppRoutes } from './app.routing';
import { AppConfig } from './app.config';
import { AppComponent } from './app.component';
import { NavigationComponent } from './navigation/navigation.component';
import { SharedModule } from './shared/shared.module';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { BreadcrumbsComponent } from './navigation/breadcrumbs/breadcrumbs.component';
import { TitleComponent } from './navigation/title/title.component';
#NgModule({
declarations: [
AppComponent,
NavigationComponent,
BreadcrumbsComponent,
TitleComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
RouterModule.forRoot(AppRoutes),
SharedModule,
HttpClientModule,
HttpModule,
JsonpModule,
FormsModule
],
providers: [AppConfig,
{
provide: APP_INITIALIZER,
useFactory: (config: AppConfig) => () => config.load('project_q_1234.json'),
deps: [AppConfig],
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
dashboard.component.ts
import { Component, OnInit } from '#angular/core';
import { Chart } from 'chart.js';
import { AppConfig } from '../../app.config';
declare var Chart;
#Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: [
'./dashboard.component.css'
]
})
export class DashboardComponent implements OnInit {
constructor(public appConfig: AppConfig, private hostConfig: AppConfig, public getSummaryParameters: AppConfig) { }
ngOnInit() {
this.updates();
}
updates() {
//assign all Parameters to objects
this.objects = this.getSummaryParameters.objects;
var JsonData = this.objects.Information.data;
console.log(JsonData["0"]["0"] + " : " + JsonData["0"][1]);
}
}
programmer.component.ts
import { Component, OnInit, ViewEncapsulation } from '#angular/core';
import { Chart } from 'chart.js';
import { CommonModule } from '#angular/common';
import { NgbModal, ModalDismissReasons } from '#ng-bootstrap/ng-bootstrap';
import { AppConfig } from '../../app.config';
declare function ChangeSortOrder(): any;
#Component({
selector: 'app-simple-page',
templateUrl: './programmer.component.html'
})
export class ProgrammerComponent implements OnInit {
objects;
constructor(public appConfig: AppConfig, private hostConfig: AppConfig, public getSummaryParameters: AppConfig, private modalService: NgbModal) { }
ngOnInit() {
this.updateData();
}
updateData() {
//assign all Parameters to objects
this.objects = this.getSummaryParameters.objects;
}
}
navigation.component.ts
import { Component, ElementRef, OnInit, ViewChild, Injectable, NgModule } from '#angular/core';
import { Router, ActivatedRoute } from '#angular/router';
import { Http } from "#angular/http";
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import { AppConfig } from '../app.config';
import { DashboardComponent } from '.././pages/dashboard/dashboard.component';
import { ProgrammerComponent } from '.././pages/programmer/programmer.component';
#Component({
selector: 'app-admin',
templateUrl: './navigation.component.html',
providers: [DashboardComponent, ProgrammerComponent]
})
#Injectable()
export class NavigationComponent implements OnInit {
fileName: any;
selectedfileName: any;
config: any;
objects: any;
constructor(public menuItems: MenuItems, private http: Http, private appConfig: AppConfig, public router: Router,
private hostConfig: AppConfig, public getSummaryParameters: AppConfig, private dashboardComponent: DashboardComponent,
private programmerComponent: ProgrammerComponent) {
}
ngOnInit() {
this.appConfig.loadMetadata().then(fileName => {
this.fileName = this.appConfig.fileName;
//Initial loading for project Drop-down, Fetch first JSON from metadata.json
this.selectedfileName = 'project_q_1234.json';
});
}
refreshApp(projectName) {
this.appConfig.load(projectName).then(objects => {
this.objects = objects;
this.updateData();
//this commented code partially works but data is not loading properlly
//this.dashboardComponent.updates();
//this.programmerComponent.updateData();
//this.qCProgrammerComponent.updateQCData();
});
}
updateData() {
console.log("Dropdown change start");
//load all the host related settings
this.config = this.hostConfig.config;
localStorage.setItem('url', this.config.host);
localStorage.setItem('folder', this.config.folder);
}
As you can't share a demo, I made my own to show how to load data from API / local json you can try from here.
Feel free to ask if it's not the scenario you want / I understand wrong.
DEMO
Here two things are done, first of all, get the metadata from constructor which will load your data on initializing your app, second select a click method in options to get the selected data and then that data can send to the url to get another data.
I don't know which css framework you using I used here angular material 2.
app.component.html
<p>
Using jsonplaceholder.typicode.com API
</p>
<mat-form-field style="width: 100%">
<mat-select placeholder="Select Any Users" [(value)]="selectedUser">
<mat-option *ngFor="let meta of metadata" (click)="getInfoAboutIndividualMeta(meta)" [value]="meta.name">
{{ meta.name }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field style="width: 100%" *ngIf="selectedUser">
<mat-select placeholder="Select Posts from {{selectedUser}}">
<mat-option *ngFor="let post of posts" (click)="selectedPost(post)" [value]="post.title">
{{ post.title }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-card *ngIf="selectPost">
<h1>{{selectPost?.title}}</h1>
<p [innerHTML]="selectPost?.body"></p>
</mat-card>
app.component.ts
name = 'Angular 6';
metadata: any[];
posts: any[];
selectedUser: string;
selectPost: Object;
constructor(private appConfig: AppConfig) {
this.metadata = [];
this.posts = [];
this.initialize();
}
initialize() {
this.appConfig.getMetadataJSON().subscribe(res => {
this.metadata = res;
this.selectedUser = this.metadata[0].name;
});
}
getInfoAboutIndividualMeta(meta: Object) {
console.log(meta);
const userId = meta.id;
this.appConfig.getIndividualMetadataJSON(userId).subscribe( res => {
this.posts = res;
});
}
selectedPost(post: Object) {
this.selectPost = post;
}
app-config.class.ts
import { Injectable } from '#angular/core';
import { HttpClient } from "#angular/common/http";
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import { Observable } from 'rxjs';
#Injectable()
export class AppConfig {
constructor(private httpClient: HttpClient) {
}
public getMetadataJSON(): Observable<any> {
// Due to stackblitz can't get the local access I put this value to another api source
// const apiUrl = './assets/metadata.json'; // You can use this as well
const apiUrl = 'https://jsonplaceholder.typicode.com/users';
return this.httpClient.get(apiUrl);
}
public getIndividualMetadataJSON(userId: number): Observable<any> {
const apiUrl = 'https://jsonplaceholder.typicode.com/posts?userId=' + userId;
return this.httpClient.get(apiUrl);
}
}