Why is the primeng dropdown list no firing? - javascript

Disclaimer, I am very new to primeng...
I have the following component
import { Component , OnInit} from '#angular/core';
import { TimeRangesService } from './time.range.service';
#Component({
moduleId : module.id,
selector: 'time-range',
templateUrl: './time.range.component.html',
})
export class TimeRangesControl implements OnInit {
timeRanges: any[];
selectedTimeRange: any;
constructor(private timeRangeService: TimeRangesService) { }
ngOnInit() {
this.timeRangeService.get().then(res => this.timeRanges = res);
}
onChange($event) {
console.log('event');
}
}
I never get the onChange function called.
In my html file, I say:
<div class="content-section implementation">
<p-dropdown
[style]="{'width': '40%', 'height': '30px'}"
onChange="onChange"
[options]="timeRanges"
[(ngModel)]="selectedTimeRange"
placeholder="Select a time range"></p-dropdown>
<p>Selected Time Range: {{selectedTimeRange ? selectedTimeRange.name : 'none'}}</p>
Any ideas what I am doing wrong?

Make the following changes:
html:
(onChange)="onChange($event)"
component.ts:
onChange(event) {
console.log(event);
}
Hope this resolves your problem.

Related

Angular: hiding a component with *ngIf doesn't work

I have just started with Angular and have already faced an issue: a button actually toggles the variable I need (show) but it doesn't affect the course.component
course.component must show app-csgo-course, boolean show is true because the component is visible, but after it toggles in navbar.component, nothing changes.
<app-csgo-course *ngIf="show"> </app-csgo-course>
import { NavbarComponent } from './../navbar/navbar.component';
import { Component, OnInit} from '#angular/core';
import { CourseService } from 'src/app/course.service';
#Component({
selector: 'app-course',
templateUrl: './course.component.html',
styleUrls: ['./course.component.css']
})
export class CourseComponent implements OnInit {
constructor() { }
ngOnInit(): void { }
service = new CourseService;
show = this.service.GetShow();
}
In navbar.component there's a button which toggles the "show" variable
<button (click)="ToggleShow()" >
<li class="nav-item active" id="csgo-logo">
<a href="#">
<img class="game-logo" src="assets\img\csgo-logo.png" title="Counter Strike: Global Offensive">
<!-- <a>CS:GO <span class="sr-only">(current)</span></a> -->
</a>
</li>
</button>
import { CourseService } from 'src/app/cheat.service';
import { Component, OnInit, Input, Output, } from '#angular/core';
#Component({
selector: 'app-navbar',
templateUrl: './navbar.component.html',
styleUrls: ['./navbar.component.css']
})
export class NavbarComponent implements OnInit {
service = new CourseService;
show = this.service.GetShow();
ngOnInit(): void {
}
public ToggleShow() {
this.service.show = this.service.ToggleShow();
console.log(this.service.show);
return this.service.show;
}
}
The course.service file
#Injectable({
providedIn: 'root'
})
export class CourseService {
show: boolean = true;
GetShow() {
return this.show;
}
ToggleShow() {
return this.show = !this.show
}
constructor() { }
}
}
Would appreciate your help!
Since you are new to Angular, let me break it down for you.
You need to create a BehaviorSubject to capture the event of toggle (this is called reactive programming which is a achieved using RxJS in Angular ).
Do not use new for a service, rather inject it in constructor.
course.service
#Injectable({
providedIn: 'root'
})
export class CourseService {
private show: boolean = true;
private toggle$ = new BehaviorSubject<boolean>(true);
constructor() { }
toggleEvent() {
return this.toggle$.asObservable();
}
toggleShow() {
this.show = !this.show
this.toggle$.next(this.show);
}
}
in NavbarComponent
import { CourseService } from 'src/app/cheat.service';
import { Component, OnInit, Input, Output, } from '#angular/core';
#Component({
selector: 'app-navbar',
templateUrl: './navbar.component.html',
styleUrls: ['./navbar.component.css']
})
export class NavbarComponent implements OnInit {
show = boolean;
// IMP: make sure to inject the service and not do "new CourseService;"
constructor(public service: CourseService){}
ngOnInit(): void {
this.service.toggleEvent().subscribe(showFlag => {
this.show = showFlag;
})
}
public ToggleShow(): void {
this.service.toggleShow();
}
}
in courseComponent
import { Component, OnInit} from '#angular/core';
import { CourseService } from 'src/app/course.service';
#Component({
selector: 'app-course',
templateUrl: './course.component.html',
styleUrls: ['./course.component.css']
})
export class CourseComponent implements OnInit {
show: boolean ;
// IMP: make sure to inject the service and not do "new CourseService;"
constructor(public service: CourseService){}
ngOnInit(): void {
this.service.toggleEvent().subscribe(showFlag => {
this.show = showFlag;
})
}
}
PS: I would suggest you to read about "how to unsubscribe an observable" and how it causes memory leaks. Once you get some idea, you should implement that in the above provided code as well. That's a best practice. Happy learning. Let me know if you have any more questions

How do I pass data from one component to another (New Browser Tab) in angular?

I'm new to angular and I don't know how to pass data between two components using routers. This is my first component view,
when I press view report button I need to call another component with the first component data. This is my first component view report click button code.
<button type="button" (click)="onFuelViewReport()" class="btn btn-success ">
<b>view Report</b>
</button>
when clicking the button it calls onFuelViewReport() function in the first component and using this function it opens the second component view with a new browser window (tab). What I want is to pass data from the first component to the second component from here. Please help me to do this.
onFuelViewReport() {
this.router.navigate([]).then(result => {
window.open("/pages/view-report", "_blank");
});
}
If you want to share data from child component to parent component, you can use #Output event emitter or if your are trying to share data within unrelated components, you can use BehaviourSubject (This also works in case of parent to child component communication and vice versa).
Child to Parent: Sharing Data via Output() and EventEmitter
parent.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-parent',
template: `
Message: {{message}}
<app-child (messageEvent)="receiveMessage($event)"></app-child>
`,
styleUrls: ['./parent.component.css']
})
export class ParentComponent {
constructor() { }
message:string;
receiveMessage($event) {
this.message = $event
}
}
child.component.ts
import { Component, Output, EventEmitter } from '#angular/core';
#Component({
selector: 'app-child',
template: `
<button (click)="sendMessage()">Send Message</button>
`,
styleUrls: ['./child.component.css']
})
export class ChildComponent {
message: string = "Hola Mundo!"
#Output() messageEvent = new EventEmitter<string>();
constructor() { }
sendMessage() {
this.messageEvent.emit(this.message)
}
}
Unrelated Components: Sharing Data with a Service
data.service.ts
import { Injectable } from '#angular/core';
import { BehaviorSubject } from 'rxjs';
#Injectable()
export class DataService {
private messageSource = new BehaviorSubject('default message');
currentMessage = this.messageSource.asObservable();
constructor() { }
changeMessage(message: string) {
this.messageSource.next(message)
}
}
parent.component.ts
import { Component, OnInit } from '#angular/core';
import { DataService } from "../data.service";
#Component({
selector: 'app-parent',
template: `
{{message}}
`,
styleUrls: ['./sibling.component.css']
})
export class ParentComponent implements OnInit {
message:string;
constructor(private data: DataService) { }
ngOnInit() {
this.data.currentMessage.subscribe(message => this.message = message)
}
}
sibling.component.ts
import { Component, OnInit } from '#angular/core';
import { DataService } from "../data.service";
#Component({
selector: 'app-sibling',
template: `
{{message}}
<button (click)="newMessage()">New Message</button>
`,
styleUrls: ['./sibling.component.css']
})
export class SiblingComponent implements OnInit {
message:string;
constructor(private data: DataService) { }
ngOnInit() {
this.data.currentMessage.subscribe(message => this.message = message)
}
newMessage() {
this.data.changeMessage("Hello from Sibling")
}
}
The window.open looks absolutely awful. Use this.router.navigate(['/heroes']);.
So if I understand correctly you have a list of items and when you click on one of the items, the details page of that item should open?
Best practice is to allow the detail route to have a property to set. the Angular Routing & Navigation page is very complete. It shows that you should use :id - { path: 'hero/:id', component: HeroDetailComponent }. When you open the detail page, you get the id variable and then get the data for it.

How to update other component html text value

This is my app.component.html source code:
<split-flap></split-flap>
<button (click)="flip('+')">+</button><button (click)="flip('-')">-</button>
This is my app.component.ts source code:
import { Component } from '#angular/core';
import { SplitFlapComponent } from './split-flap/split-flap.component';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers:[SplitFlapComponent]
})
export class AppComponent {
constructor(private splitFlapComponent: SplitFlapComponent)
{
}
flip(flag)
{
console.log(flag);
this.splitFlapComponent.title=flag;
}
}
This is my split-flap.component.ts:
import { Component, OnInit, Input, Output } from '#angular/core';
#Component({
selector: 'split-flap',
templateUrl: './split-flap.component.html',
styleUrls: ['./split-flap.component.css']
})
export class SplitFlapComponent implements OnInit {
title: string;
constructor() {
this.title = 'split-flap works1!';
}
ngOnInit() {
}
}
This is my split-flap.component.html:
<p>{{title}}</p>
My app.component.html has two buttons, both of them pass a sign to split-flap.component, would you tell me how can I the update split-flap.component.html content? Because most of the examples for input box only, I cannot find an example for <p>.
Try like this:
Solution 1 : #Input()
app.component.html
<split-flap [title]="title"></split-flap>
app.component.ts
title: string;
constructor() {
this.title = 'split-flap works1!';
}
flip(flag)
{
console.log(flag);
this.title=flag;
}
split-flap.component.ts:
#Input() title: string
Solution 2 : ViewChild()
app.component.html
<split-flap #child ></split-flap>
app.component.ts
#ViewChild('child') child: SplitFlapComponent ;
flip(flag)
{
console.log(flag);
this.child.title=flag;
}

ng2 [disabled]="!myInput.value" doesnt work correctly

I'm building a standard angular2 app(more specific a todo app). I also added #Ngrx/store.
The first time I load the page, the button is disabled, but when I enter some value in the input box, the button needs to be enabled, but it stays disabled...
app/app.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
template: `
<h1>Hello {{name}}</h1>
<div>
<add-todo></add-todo>
</div>`,
})
export class AppComponent { name = 'Angular'; }
app/components/add-todo/add-todo.component.ts
import { Component, ViewChild, ElementRef } from '#angular/core';
#Component({
moduleId: module.id,
selector: 'add-todo',
template: `
Create new todo
<input #myInput />
<button (click)="addTodo()" [disabled]="!myInput.value">Add</button>`
})
export class AddTodoComponent {
#ViewChild('myInput') input: ElementRef;
constructor() {}
addTodo(): void {
alert(this.input.nativeElement.value);
}
}
From the documentation https://angular.io/docs/ts/latest/guide/forms.html Track the change state and validity of form controls using ngModel...
Update your code to use ngModel and it should work as expected
import { Component, ViewChild, ElementRef } from '#angular/core';
#Component({
moduleId: module.id,
selector: 'add-todo',
template: `
Create new todo
<input #myInput [(ngModel)]="inputFieldValue" />
<button (click)="addTodo()" [disabled]="!myInput.value">Add</button>`
})
export class AddTodoComponent {
#ViewChild('myInput') input: ElementRef;
public inputFieldValue:string = '';
constructor() {}
addTodo(): void {
alert(this.input.nativeElement.value);
}
}
What if you do this way:
import {Component} from '#angular/core';
#Component({
selector: 'add-todo',
template: `
Create new todo
<input #todoTitleInput [(ngModel)]="todoTitle"/>
<button (click)="addTodo(todoTitleInput.value)" [disabled]="!todoTitle">Add</button>
`,
})
export class AddTodoComponent {
addTodo(title: string): void {
alert(title);
}
}

Access Angular 2 Inputs (properties) inside constructor

I'm creating some components in order to learn Angular2.
I have this basic html:
<h1>test</h1>
<btn [order]="0"></btn>
<btn [order]="1"></btn>
<btn [order]="2"></btn>
And in the ts I have this:
import {Component, Input} from 'angular2/core';
import {DataService} from '../services/DataService';
#Component({
selector: 'btn',
template: '<button>test{{ item }}</button>',
inputs: ['order']
})
export class ButtonComponent {
items: Array<number>;
item: number;
#Input() order;
constructor(dataService: DataService) {
console.log(this.order)
}
}
Doing that I get undefined, what am I doing wrong? how can I read the inputs (or an attribute) in order to send data to the class?
EDIT
import {Component, Input} from 'angular2/core';
import {DataService} from '../services/DataService';
#Component({
selector: 'btn',
template: '<button>test{{ item }}</button>',
inputs: ['order']
})
export class ButtonComponent {
items: Array<number>;
item: number;
#Input() order;
ngOnInit(dataService: DataService) {
this.items = dataService.getItems();
console.log(this.order)
}
constructor() {}
}
You can't access them in the constructor, they are not yet initialized. Use ngOnInit() instead. For more details see https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html
export class ButtonComponent implements OnInit {
items: Array<number>;
item: number;
#Input() order;
constructor(dataService: DataService) { }
ngOnInit() {
console.log(this.order);
}
}

Categories

Resources