Angular 4 - service data is not persistent - html

I am having some trouble figuring out where I went wrong and would really appreciate some help with this.
I have a component: AudioComponent, which captures an html5 tag as a #ViewChild, then registers itself with a service: AudioService.
Here is the AudioComponent:
/* audio.component.ts */
import { Component, OnInit, Input, ViewChild } from '#angular/core';
import { IAudioOptions } from './audio-options';
export const defaultOptions: IAudioOptions = {
controls: true,
autoplay: false,
loop: false,
volume: 1.0,
startPosition: 0.0,
preload: "metadata",
muted: false
};
#Component({
selector: 'ng-audio',
templateUrl: './audio.component.html',
styleUrls: ['./audio.component.css']
})
export class AudioComponent implements OnInit {
#Input() src: any;
#Input() options: any = defaultOptions;
#Input() register: any;
#ViewChild('audio') player: any;
constructor() { }
ngOnInit() {
if (this.register) {
console.log("registering");
console.log(this.register(this));
}
}
play() {
this.player.nativeElement.play();
}
}
And the AudioService:
/* audio.service.ts */
import { Injectable } from '#angular/core';
import { AudioComponent } from './audio/audio.component';
#Injectable()
export class AudioService {
private players: AudioComponent[];
constructor() { }
register(player: AudioComponent) {
console.log("player registered");
if (this.players) {
this.players.push(player);
}
else {
console.log("initializing service");
this.players = [];
this.players.push(player);
}
return this.players;
}
getPlayers(): string[] {
var out: string[];
for (let i = 0; i < this.players.length; i++) {
out.push(this.players[i].src);
}
return out;
}
}
I'm instantiating two of the ng-audio components in my app.component.html file:
<!-- register refers to the AudioService.register function -->
<ng-audio [src]="src" [register]="register"></ng-audio>
<ng-audio [src]="src2" [register]="register"></ng-audio>
And the audio players themselves appear when I load the page.
What's puzzling is that I get the following logged to the console:
- registering
- player registered
- initializing service
- [AudioComponent]
- registering
- player registered
- initializing service // <- this should only happen the first time!
- [AudioComponent] // <- and this should now contain two elements!
For some reason, the players: AudioComponent[] property of the AudioService does not persist. So each time register() is called, it's like I'm calling it on a completely new AudioService instance!
Again, any help will be greatly appreciated. I'll be posting updates if I can figure this out.
EDIT: I've included my app.module.ts and app.component.ts files in case there's something I missed setting up the service as a provider.
AppModule:
/* app.module.ts */
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppComponent } from './app.component';
import { AudioComponent } from './audio/audio.component';
import { AudioService } from './audio.service';
#NgModule({
declarations: [
AppComponent,
AudioComponent
],
imports: [
BrowserModule
],
exports: [AudioComponent],
providers: [AudioService],
bootstrap: [AppComponent]
})
export class AppModule { }
And AppComponent:
/* app.component.ts */
import { Component } from '#angular/core';
import { AudioComponent } from './audio/audio.component';
import { AudioService } from './audio.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
src = 'http://url.to/file.mp3';
src2 = 'http://url.to/another-file.mp3';
interval: any;
player: AudioComponent;
register: any;
play: any;
constructor(
private service: AudioService
) {
this.register = this.service.register;
this.play = this.service.getPlayers;
}
}

Related

TypeScript variable seems not to load the value from one file to another

I am following the tutorial here: https://coursetro.com/posts/code/154/Angular-6-Tutorial---Learn-Angular-6-in-this-Crash-Course
I currently have the code up to the section titled Fetching More Data from the API working. In short this is supposed to make a page with a bunch of users accessed through a toy API. The users are listed on a page with some personal information, and each one links to a very basic profile page displaying their details. Up to the section I mentioned above, I am successfully interfacing with the API, getting the users and displaying them and some personal information on the main page.
However, the code in this section is intended to collect an individual user's details and display them on a linked page. In trying to follow the example, my code does produce a page with the right outlines, but the value of the variable user$ and its fields like user$.name don't seem to be loaded by the details component. Where those values are supposed to show up, it's blank.
The app files:
app-routing.module.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { UsersComponent } from './users/users.component';
import { DetailsComponent } from './details/details.component';
import { PostsComponent } from './posts/posts.component';
const routes: Routes = [
{
path: '',
component: UsersComponent
},
{
path: 'details/:id',
component: DetailsComponent
},
{
path: 'posts',
component: PostsComponent
}
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
app.component.html
<div id="container">
<app-sidebar></app-sidebar>
<div id="content">
<router-outlet></router-outlet>
</div>
</div>
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { SidebarComponent } from './sidebar/sidebar.component';
import { PostsComponent } from './posts/posts.component';
import { UsersComponent } from './users/users.component';
import { DetailsComponent } from './details/details.component';
import { HttpClientModule } from '#angular/common/http';
#NgModule({
declarations: [
AppComponent,
SidebarComponent,
PostsComponent,
UsersComponent,
DetailsComponent
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
data.service.ts
import { Injectable } from '#angular/core';
import {HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class DataService {
constructor(private http: HttpClient) { }
getUsers() {
return this.http.get('https://jsonplaceholder.typicode.com/users')
}
getUser(userId) {
return this.http.get('https://jsonplaceholder.typicode.com/users'+userId)
}
getPosts() {
return this.http.get('https://jsonplaceholder.typicode.com/posts')
}
}
users files:
users.component.html
<h1>Users</h1>
<ul>
<li *ngFor="let user of users$">
{{user.name}}
<ul>
<li>{{user.email}}</li>
<li>{{user.website}}</li>
</ul>
</li>
</ul>
users.component.ts
import { Component, OnInit } from '#angular/core';
import { DataService } from '../data.service';
import { Observable } from 'rxjs';
#Component({
selector: 'app-users',
templateUrl: './users.component.html',
styleUrls: ['./users.component.scss']
})
export class UsersComponent implements OnInit {
users$: Object;
constructor(private data: DataService) { }
ngOnInit() {
this.data.getUsers().subscribe(
data => this.users$ = data
);
}
}
details files:
details.component.html
<h1>{{ user$.name }}</h1>
<ul>
<li><strong>Username: </strong> {{user$.username}}</li>
<li><strong>Email: </strong> {{user$.email}}</li>
<li><strong>Phone: </strong> {{user$.phone}}</li>
</ul>
details.component.ts
import { Component, OnInit } from '#angular/core';
import { DataService } from '../data.service';
import { Observable } from 'rxjs';
import { ActivatedRoute } from '#angular/router';
#Component({
selector: 'app-details',
templateUrl: './details.component.html',
styleUrls: ['./details.component.scss']
})
export class DetailsComponent implements OnInit {
user$: Object;
constructor(private data: DataService, private route: ActivatedRoute) {
this.route.params.subscribe( params => this.user$ = params.id );
console.log(this.route.params);
}
ngOnInit() {
this.data.getUser(this.user$).subscribe(
data => this.user$ = data
);
}
}
I tried logging values to the console, but I don't fully understand how TypeScript works so I don't fully know what I really should expect from these logs. In any case, in the log that I made in the details TypeScript file, it showed an object with no apparent loading errors.
this.route.params is a Observable. I am not sure what you can get by logging it.
I would suggest you add a log when subscribing to a observable and see what kind of data you really get. Like.
this.data.getUser(this.user$).subscribe(
data => {console.log(data);this.user$ = data}
);
#Adem, As Haijin comment, you must "work" a bit in subscribe parameter. The idea is that you subscribe to get the parameter, and, when you have the parameter, you ask about the user. But you need to make in the same step using switchMap
ngOnInit()
{
//You subscribe the param. When you have ask for the user
this.route.params.subscribe( params =>
{
this.user$ = params.id;
//In subscribe you ask for the user
this.data.getUser(this.user$).subscribe(
data => this.user$ = data
)
});
}
Well, really In Angular is better don't subscribe two times else using Rjxs and switchMap
ngOnInit()
{
//You subscribe the params, but you don't want the param
this.route.params.pipe(
switchMap(params =>
{ //you want return the user
return this.data.getUser(params.id)
})
).subscribe(data => this.user$ = data)
}

Display data from json array using angular4

I am new to angular so please help me. I have an api returning an array of objects containing name, place id.
I need to display this in different cards on my html page, the cards being a widget.
in the parent component under the ngOnInit() section how do I access this json data and loop through the array in order to display it on my page as different cards?
Thank you in advance.
import { Component, OnInit } from '#angular/core';
import {HttpClient} from '#angular/common/http';
import { Observable } from 'rxjs/observable';
#Component({
selector: 'app-home-page',
templateUrl: './home-page.component.html',
styleUrls: ['./home-page.component.css']
})
export class HomePageComponent implements OnInit {
showSplash = true
//public events: any = [];
events = [];
constructor(private http : HttpClient) { }
ngOnInit() {
this.showSplash = true
this.http.get("/events").subscribe(data => {
console.log("EVENTS ARE: ", data);
this.events = data;
console.log(this.events)
})
}
ngAfterViewInit(){
setTimeout(() => {
this.showSplash = false
}, 3000);
}
}
This will get you the events you want.
import { Component, OnInit, OnDestroy } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Subscription } from 'rxjs';
#Component({
selector: 'app-home-page',
templateUrl: './home-page.component.html',
styleUrls: ['./home-page.component.css']
})
export class HomePageComponent implements OnInit, OnDestroy {
showSplash = true
events = [];
subscription: Subscription;
constructor(private http: HttpClient) {}
ngOnInit() {
this.subscription = this.http.get("/events").subscribe(data => {
this.events = data;
this.showSplash = false;
});
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
You will have to implement a Child Component(EventComponent probably with the selector app-event) that will accept an event object as an #Input property. Then in your HomePageComponent Template, you can loop through the events like this:
<div *ngFor="let event of events">
<app-event [event]="event"></app-event>
</div>
Alternatively:
You can use the async pipe in your HomePageComponent's Template to avoid manually unsubscribing from the Observable Subscription. Your HomePageComponent Class code will change to:
import { Component, OnInit } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-home-page',
templateUrl: './home-page.component.html',
styleUrls: ['./home-page.component.css']
})
export class HomePageComponent implements OnInit {
events$;
constructor(private http: HttpClient) {}
ngOnInit() {
this.events$ = this.http.get("/events");
}
}
And then in HomePageComponent's Template:
<div *ngFor="let event of events$ | async">
<app-event [event]="event"></app-event>
</div>
Here's how your EventComponent would look like in this case:
import { Component, Input, OnChanges } from '#angular/core';
#Component({
selector: 'app-event',
templateUrl: './event.component.html',
styleUrls: ['./event.component.css']
})
export class EventComponent implements OnChanges{
#Input() event;
ngOnChanges() {
this.events$ = this.http.get("/events");
}
}

Trying to pass JSON data with angular/nativescript routing

I'm currently working on a nativescript/angular/typescript project and I'm basically trying to pass JSON data from one view (property) to another (propertyinfo).
First, I load up a JSON file in property.service.ts:
import { Injectable } from '#angular/core';
import { HttpClientModule, HttpClient } from '#angular/common/http';
#Injectable()
export class PropertyService {
public propertyData: any;
public selectedProperty: any;
constructor(private http: HttpClient) {
this.loadProperties();
}
loadProperties() {
this.http.get('/pages/property/property.json').subscribe(
(data) => {
this.propertyData = data;
}
)
}
}
This JSON data gets displayed in a view property.component.html:
<StackLayout *ngFor="let item of propertyData" class="list-group" xstyle="height: 300">
<GridLayout rows="110" columns="*, 40" (tap)="details(item)">
<StackLayout row="0" col="0">
<Label text="{{item.streetName}} {{item.houseNumber}}" class="text-primary p-l-30 p-t-5"></Label>
<Label text="{{item.etc}} {{item.etc}}" class="text-primary p-l-30 p-t-5"></Label>
</StackLayout>
<Label row="0" col="1" text="" class="fa arrow" verticalAlignment="middle"></Label>
</GridLayout>
<StackLayout class="hr-light"></StackLayout>
Here, the (tap)="details(item)" will call a function in property.component.ts:
import { Component, OnInit } from '#angular/core';
import { Router } from "#angular/router";
import { PropertyService } from './property.service';
#Component({
selector: 'app-property',
templateUrl: 'pages/property/property.component.html',
providers: [PropertyService]
})
export class PropertyComponent implements OnInit {
public propertyData: any;
constructor(private router: Router, private propertyService: PropertyService) {}
ngOnInit() {
this.propertyData = this.propertyService.propertyData;
}
details(item: any) {
this.propertyService.selectedProperty = item;
this.router.navigate(["/propertyinfo"]);
}
}
Now, when I perform a console.log(JSON.stringify(this.propertyService.selectedProperty)); within my details function, the output is as follows:
JS: {"ID":4,"description":"Lorem ipsum dolor sit amet...", "streetName":"Somestreet","houseNumber":459,"etc":"etc"}
This is my propertyinfo.component.ts:
import { Component, OnInit } from '#angular/core';
import { PropertyService } from '../property/property.service';
import { Router } from '#angular/router';
#Component({
selector: 'app-propertyinfo',
templateUrl: 'pages/propertyinfo/propertyinfo.component.html'
})
export class PropertyinfoComponent implements OnInit {
public selectedProperty: any;
constructor(private propertyService: PropertyService, private router: Router) {
this.selectedProperty = this.propertyService.selectedProperty;
}
ngOnInit() { }
}
Yet, when I perform a console.log(JSON.stringify(this.selectedProperty)); inside the constructor, the output is JS: undefined.
At the bottom of this post, I'll add the app.routing.ts and app.module.ts files so you can see all of my imports/directives etc. I'm really at a loss as to what I'm missing. I hope you can help me.
app.routing.ts:
import { NgModule } from "#angular/core";
import { NativeScriptRouterModule } from "nativescript-angular/router";
import { Routes } from "#angular/router";
import { PropertyComponent } from "./pages/property/property.component";
import { PropertyinfoComponent } from ".//pages/propertyinfo/propertyinfo.component";
const routes: Routes = [
{ path: "", component: PropertyComponent },
{ path: "propertyinfo", component: PropertyinfoComponent },
];
#NgModule({
imports: [NativeScriptRouterModule.forRoot(routes)],
exports: [NativeScriptRouterModule]
})
export class AppRoutingModule { }
app.module.ts:
import { NgModule, NO_ERRORS_SCHEMA } from "#angular/core";
import { NativeScriptHttpClientModule } from "nativescript-angular/http-client";
import { HttpClientModule, HttpClient } from '#angular/common/http';
import { NativeScriptModule } from "nativescript-angular/nativescript.module";
import { NativeScriptRouterModule } from "nativescript-angular/router";
import { AppRoutingModule } from "./app.routing";
import { AppComponent } from "./app.component";
import { PropertyService } from "./pages/property/property.service";
import { PropertyComponent } from "./pages/property/property.component";
import { PropertyinfoComponent } from "./pages/propertyinfo/propertyinfo.component";
#NgModule({
bootstrap: [
AppComponent
],
imports: [
NativeScriptModule,
AppRoutingModule,
NativeScriptRouterModule,
HttpClientModule,
NativeScriptHttpClientModule,
],
declarations: [
AppComponent,
PropertyComponent,
PropertyinfoComponent
],
providers: [
PropertyService
],
schemas: [
NO_ERRORS_SCHEMA
]
})
export class AppModule { }
Thank you for any help in advance. If I need to clear things up/provide any more info, please let me know.
console.log(JSON.stringify(this.selectedProperty)) returns undefined in PropertyinfoComponent because the PropertyService service being injected is not the same instance in PropertyinfoComponent than it is in PropertyComponent
you did not post the full .html for both component so I can only assume that you have something like the PropertyComponent is a parent component and has a reference/include a PropertyinfoComponent in the html and because of the way angular work, it injected a new instance of the service instead of using the one from the parent component.
check Thierry Templier answer for more information about angular service injection for this type of issue : How do I create a singleton service in Angular 2?

Parent / Child component communication angular 2

I am failing to implement action button in child_1 component but the event handler is in sub child component child_2 as shown in the following code:
app.component.html (Parent Html)
<div style="text-align:center">
<h1>
Welcome to {{title}}!
</h1>
<app-navigation></app-navigation> <!-- Child1-->
</div>
app.component.html (Parent Component)
import { Component } from '#angular/core';
import { ProductService } from './productservice';
import {Product} from './product';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
title = 'MobileShirtShoeApp';
}
app.module.ts (Main Module)
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { HttpModule } from '#angular/http';
import { Product } from './product';
import { ProductService } from './productservice';
import { AppComponent } from './app.component';
import { NavigationComponent } from './navigation/navigation.component';
import { DataTemplateComponent } from './data-template/data-template.component';
#NgModule({
declarations: [AppComponent,NavigationComponent,DataTemplateComponent],
imports: [BrowserModule,HttpModule],
providers: [ProductService],
bootstrap: [AppComponent]
})
export class AppModule { }
navigation.component.html (Child 1 HTML)
<fieldset>
<legend>Navigate</legend>
<div>
<button (click)="loadMobiles()">Mobiles</button> <!--Child_1 Action-->
</div>
<app-data-template></app-data-template>
</fieldset>
navigation.component.ts (Child 1 Component.ts)
import { Component, OnInit } from '#angular/core';
import { ProductService } from '../productservice';
import {Product} from '../product';
import {DataTemplateComponent} from '../data-template/data-template.component';
#Component({
selector: 'app-navigation',
templateUrl: './navigation.component.html',
styleUrls: ['./navigation.component.css']
})
export class NavigationComponent implements OnInit {
error: string;
productArray: Product[];
constructor(private myService: ProductService){
this.myService = myService;
}
dataTemplateComponent: DataTemplateComponent = new DataTemplateComponent(this.myService);
ngOnInit() {
}
loadMobiles() {
return this.dataTemplateComponent.loadMobiles();
}
}
data-template.component.html (Child 2 HTML) (NOT DISPLAYING DATA)
<fieldset>
<legend>Requested Data</legend>
Welcome
<div>
<ul>
<li *ngFor="let product of productArray">
{{product.id}} {{product.name}} {{product.price}}
<img src="{{product.url}}">
</li>
</ul>
</div>
</fieldset>
data-template.component.ts (Child 2 Component) (Contains Product service calling code)
import { Component} from '#angular/core';
import {Product} from '../product';
import {ProductService} from '../productservice';
#Component({
selector: 'app-data-template',
templateUrl: './data-template.component.html',
styleUrls: ['./data-template.component.css']
})
export class DataTemplateComponent {
error: string;
productArray: Product[];
constructor(private productService: ProductService) {
this.productService = productService;
}
loadMobiles(){
let promise = this.productService.fetchMobiles();
promise.then(productArr => {
return this.productArray = productArr;
}).catch((err) => {
this.error = err;
});
}
}
ProductService.ts
import 'rxjs/add/operator/toPromise';
import {Http, HttpModule} from '#angular/http';
import {Injectable} from '#angular/core';
import {Product} from './product';
#Injectable()
export class ProductService{
http: Http;
constructor(http: Http){
this.http = http;
console.log(http);
}
fetchMobiles(): Promise<Product[]>{
let url = "https://raw.githubusercontent.com/xxxxx/Other/master/JsonData/MobileData.json";
return this.http.get(url).toPromise().then((response) => {
return response.json().mobiles as Product[];
}).catch(this.handleError);
}
private handleError(error: any): Promise<any> {
console.error('An error occurred', error);
return Promise.reject(error.message || error);
}
}
Sorry if the code bothers you. So basically i am failing to display service data in child_2.html when an action made in child_1.html.The service working fine and name is ProductService which uses Product.ts as an object to get the data in JSON format. Any kind of help is appreciated.
This doesn't work because the DataTemplateComponent you're instantiating in app-navigation isn't the same instance of DataTemplateComponent as the one on the page. It's a brand new one that you instantiated and that isn't bound to the page at all. What you're trying to achieve is component communication. Specifically, parent / child component communication. There are a number of ways to do this, the cleanest and most flexible / extensible way is with a shared service pattern. Basically, you declare a service with an observable in it that you inject into both services and one updates the observable while the other is subscribed to it, like this:
#Inject()
export class MyComponentCommunicationService {
private commSubject: Subject<any> = new Subject();
comm$: Observable<any> = this.commSubject.asObservable();
notify() {
this.commSubject.next();
}
}
Then provide this service, either at the app module or possibly at the parent component depending on needs then in app navigation:
constructor(private commService: MyComponentCommunicationService) {}
loadMobiles() {
this.commservice.notify();
}
and in data template:
constructor(private commService: MyComponentCommunicationService, private productService: ProductService) {}
ngOnInit() {
this.commSub = this.commService.comm$.subscribe(e => this.loadMobiles());
}
ngOnDestroy() { this.commSub.unsubscribe(); } // always clean subscriptions
This is probably a little unneccessary since you already have the product service there. You could probably just move the load mobiles logic into the product service and have that trigger an observable that the data template service is subscribed to, and have the nav component call the load mobile method on the product service, but this is just meant to illustrate the concept.
I'd probably do it like this:
#Inject()
export class ProductService {
private productSubject: Subject<Product[]> = new Subject<Product[]>();
products$: Observable<Product[]> = this.productSubject.asObservable();
loadMobiles() {
this.fetchMobiles().then(productArr => {
this.productSubject.next(productArr);
}).catch((err) => {
this.productSubject.error(err);
});
}
}
then nav component:
loadMobiles() {
this.myService.loadMobiles();
}
then data template:
ngOnInit() {
this.productSub = this.productService.products$.subscribe(
products => this.productArray = products,
err => this.error = err
);
}
ngOnDestroy() { this.productSub.unsubscribe(); } // always clean subscriptions

Dynamic tab navigation system using Angular 2

I want to create a dynamic tabs navigation system using Angular 2.
Basically I want to first display a single tab that contains a single component, containing clickable objects (like links, buttons...).
I would like that a click on one of those links adds a new tab, and that a click on each tab (the initial one and the newly created tab) displays a corresponding component in display zone (router-outlet) below.
This is what I've tried so far:
app.component.ts (Root component and "tabs container):
import { Component, OnInit } from '#angular/core';
import { TabComponent } from './tab/tab.component';
import { FirstComponent } from './test/first.component';
import { SecondComponent } from './test/second.component';
import { ThirdComponent } from './test/third.component';
import { ROUTER_DIRECTIVES } from '#angular/router';
#Component({
selector: 'my-app',
templateUrl: './app/app.component.html',
directives: [TabComponent, ROUTER_DIRECTIVES, FirstComponent, SecondComponent, ThirdComponent],
})
export class AppComponent implements OnInit{
tabList: any[];
constructor() {}
ngOnInit() {
this.tabList = [
{
name: 'link 1',
link: "/comp1"
},
{
name: 'link 2',
link: "/comp2"
},
{
name: 'link 3',
link: "/comp3"
}
]
}
}
app.component.html:
<h1>Tabs container</h1>
<div>
<nav>
<tab *ngFor="let tab of tabList" [name]="tab.name" [link]="tab.link"></tab>
</nav>
</div>
<div>
<router-outlet></router-outlet>
</div>
Each tab is represented by a tab.component.ts:
import { ROUTER_DIRECTIVES, Router } from '#angular/router';
import { Component, OnInit, Input } from '#angular/core';
#Component({
selector: 'tab',
templateUrl: './app/tab/tab.component.html',
directives: [ROUTER_DIRECTIVES]
})
export class TabComponent implements OnInit {
#Input() name: string;
#Input() link: string;
#Input() param: string;
targetArray: Array<any>;
constructor(private router: Router) {}
ngOnInit() {
}
}
which template is tab.component.html:
<a [routerLink]='link'>{{name}}</a>
Here is the app.routes.ts file:
import { provideRouter, RouterConfig } from '#angular/router';
import { TabComponent } from './tab/tab.component';
import { FirstComponent } from './test/first.component';
import { SecondComponent } from './test/second.component';
import { ThirdComponent } from './test/third.component';
export const routes: RouterConfig = [
{
path: '',
component: TabComponent
},
{
path: 'comp1',
component: FirstComponent
},
{
path: 'comp2',
component: SecondComponent
},
{
path: 'comp3',
component: ThirdComponent
},
];
export const APP_ROUTER_PROVIDERS = [
provideRouter(routes)
];
Here is for example the first.component.ts (SecondComponent and ThirdComponent are similar):
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'first',
template: `<h1>First</h1>
<button (click)="addTab()">Display child</button>
`
})
export class FirstComponent implements OnInit {
constructor() {}
ngOnInit() {
}
addTab(){
}
}
I would like to put the tab creation logic in the addTab() method to basically add an element to the tabList array in app.component.ts and obtain the desired behavior but I don't know how to transfer data from this component to the app.component.ts.
I also open to any different approach and suggestions.
You can inject the Router into your component and use the config method to configure dynamic links.
router.config([
{ 'path': '/', 'component': IndexComp },
{ 'path': '/user/:id', 'component': UserComp },
]);
The documentation for the Router service can be found here.