Angular 6 - Class variables - javascript

If I have a component like this:
import { Component, OnInit, ViewChild } from '#angular/core';
#Component({
selector: '...',
templateUrl: './...html',
styleUrls: ['./...scss']
})
export class TestClass implements OnInit {
testVariable : string = 'Test';
constructor() { }
ngOnInit() {}
printTest(): void{
console.log(this.testVariable);
}
}
If I call printTest method from an another component, the result will be undefined. Why? How can I figure out this?

Typo here
console.log(this.tetsVariable);
should be
console.log(this.testVariable);

Related

Angular - How to invoke function from parent to child component

I have this situation: A parent component structured in this way:
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
with this html (parent has an ng-content):
<div>
<ng-content></ng-content>
<button>Click to say Hello!!!</button>
</div>
and a child component like this:
import { Component, OnInit } from "#angular/core";
#Component({
selector: "app-child",
templateUrl: "./child.component.html",
styleUrls: ["./child.component.css"]
})
export class ChildComponent implements OnInit {
onSubmit() {
alert("hello");
}
constructor() {}
ngOnInit() {}
}
with this html:
<div>I'm child component</div>
From the parent component I want to click inside button to invoke onSubmit child function...is this possible?
<app-parent>
<app-child>
</app-child>
</app-parent>
This is a sample; I'm creating a modal that has default buttons: "CANCEL" and "SUCCESS". On the success button I need to invoke one function declared into the childrenComponent.
This is the stackblitz example: https://stackblitz.com/edit/angular-ivy-vuctg4
You can access like that
app.component.html
<hello name="{{ name }}"></hello>
<app-parent (clickActionCB)="clickActionCB($event)">
<app-child></app-child>
</app-parent>
app.component.ts
import { Component, VERSION, ViewChild } from "#angular/core";
import { ChildComponent } from "./child/child.component";
#Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
name = "Angular " + VERSION.major;
#ViewChild(ChildComponent) childRef: ChildComponent;
clickActionCB(eventData) {
this.childRef.onSubmit() ;
}
}
parent.component.ts
import { Component, EventEmitter, OnInit, Output } from "#angular/core";
#Component({
selector: "app-parent",
templateUrl: "./parent.component.html",
styleUrls: ["./parent.component.css"]
})
export class ParentComponent implements OnInit {
constructor() {}
ngOnInit() {}
#Output() clickActionCB = new EventEmitter<string>();
clickAction() {
this.clickActionCB.emit();
}
}
parent.component.html
<div>
<ng-content></ng-content>
<button (click)="clickAction()">Click to say Hello!!!</button>
</div>
Live stackblitz URL
child.component.ts
import { Component, OnInit } from "#angular/core";
#Component({
selector: "app-child",
template: `
<div>I'm child component</div>
`
})
export class ChildComponent implements OnInit {
onSubmit() {
alert("hello");
}
constructor() {}
ngOnInit() {}
}
parent.component.ts
import { ChildComponent } from "../child/child.component";
#Component({
selector: "app-parent",
template: `
<div>
<ng-content></ng-content>
<button (click)="onClick()">Click to say Hello!!!</button>
</div>
`
})
export class ParentComponent implements OnInit {
#ContentChild(ChildComponent) childRef: ChildComponent;
constructor() {}
ngOnInit() {}
onClick() {
this.childRef.onSubmit();
}
}
https://stackblitz.com/edit/angular-ivy-mteusj?file=src%2Fapp%2Fparent%2Fparent.component.ts

Angular app is compiling successfully but giving errors property does not exist in 'ng build --prod'

Angular app is compiling successfully but giving the following errors in 'ng build --prod'
ERROR in src\app\header\header.component.html(31,124): : Property 'searchText' does not exist on type 'HeaderComponent'.
src\app\dashboard\dashboard.component.html(3,72): : Property 'newsService' is private and only accessible within class 'DashboardComponent'.
src\app\dashboard\dashboard.component.html(3,72): : Property 'p' does not exist on type 'DashboardComponent'.
src\app\dashboard\dashboard.component.html(29,46): : Property 'p' does not exist on type 'DashboardComponent'.
I have used these properties in my html file as below:
header.component.htmlfile
<input type="text" class="form-control mr-2 align-self-center" required placeholder="Search" name="searchText" [ngModel]="searchText" value="">
dashboard.component.htmlfile
<pagination-controls class="text-center" (pageChange)="p = $event"></pagination-controls>
my header.component.html file
import { Component, OnInit, Output, EventEmitter, ViewEncapsulation } from '#angular/core';
import { NgForm } from '#angular/forms';
#Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
filterText : string;
#Output() search = new EventEmitter();
#Output() filterButton = new EventEmitter();
constructor() { }
ngOnInit() {
}
onSubmit(form : NgForm)
{
console.log(form);
this.search.emit(form);
}
filterClicked($event)
{
this.filterText = $event.target.text;
this.filterButton.emit(this.filterText);
}
}
my dashboard.component.html file
import { Component, OnInit, ViewEncapsulation } from '#angular/core';
import { NewsService } from '../shared/news.service';
import { NewsModel } from '../shared/news.model';
import { Form } from '#angular/forms';
import { Pipe, PipeTransform } from '#angular/core';
import { element } from 'protractor';
#Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {
articles : any;
temp : NewsModel = new NewsModel;
constructor(private newsService : NewsService) { }
ngOnInit() {
this.FetchHeadlines();
}
FetchHeadlines()
{
this.newsService.GetAllGaurdian()
.subscribe((result) =>
{
this.articles = result;
this.articles.response.results.forEach(element => {
this.newsService.newsArticles.push(this.newsService.CusotomMapper(element));
});
})
}
}
can't able to figure out where is the error exactly!
I think the error descriptions are as accurate as it can be. each of them tells you that something wrong with your component, lets examine each of them
ERROR:
ERROR in src\app\header\header.component.html(31,124): : Property 'searchText' does not exist on type 'HeaderComponent'.
you have searchText in HeaderComponent HTML, but not in the Component itself
SOLUTION: add searchText variable to the Component
#Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
searchText:string
...
}
ERROR :
src\app\dashboard\dashboard.component.html(3,72): : Property 'newsService' is private and only accessible within class 'DashboardComponent'.
all the fields you are using inside the template, must be the public field inside component itself, otherwise it will not compile
SOLUTION: change private modifier to public at newService
#Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {
constructor(public newsService : NewsService) { }
...
}
ERRORS :
src\app\dashboard\dashboard.component.html(3,72): : Property 'p' does not exist on type 'DashboardComponent'.
src\app\dashboard\dashboard.component.html(29,46): : Property 'p' does not exist on type 'DashboardComponent'.
same as HeaderComponent. you are using p field but it's not defined in DashboardComponent
SOLUTION : add p field to the dashboard component
#Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {
p:any
...
}
You are trying to access from the template, variables that aren't defined in the corresponding components.
In header.component.html you are setting [ngModel]="searchText" and variable searchText isn't defined on header.component.ts. Could it be filterText variable instead?
In dashboard.component.html you are setting p = $event and variable p isn't defined on dashboard.component.ts. You also have an error about newsService being private. If you are gonna use it in the template it must be declared public when you inyect it on the constructor. I hope this helps. If you need more help is better if you provide a Stackblitz with minimum code.

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;
}

function share in header and sidebar component angular 6

I need to sidebar component function in sidebar.
my header component
import { Component, OnInit, Input,ViewChild } from '#angular/core';
import { SidebarComponent } from '../sidebar/sidebar.component';
#ViewChild(SidebarComponent) SidebarComponent;
ngOnInit() {
this.SidebarComponent.testFunction();
}
sidebar component
testFunction() {
console.log('value');
}
I added an essential code block for the understanding purpose. when I use the above code error said,
ERROR TypeError: Cannot read property 'testFunction' of undefined
at HeaderComponent.push../src/app/layout/components/header/header.component.ts.HeaderComponent.ngOnInit (header.component.ts:57)
can u help me to fix this issue?
call it after child view is initialized.
#ViewChild(SidebarComponent) sidebarComponent: SidebarComponent;
ngAfterViewInit() {
this.sidebarComponent.testFunction();
}
For sharing of functions in Angular, it is better to use a service and call it's functions in both of the components.
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root',
})
export class SharedService {
constructor() { }
sharedFunction(){
console.log('here');
}
}
And in both of components, component1:
import { SharedService } from '../shared.service';
import { Component, OnInit } from '#angular/core';
#Component({
selector: '.....',
templateUrl: '.......',
styleUrls: ['........']
})
export class Component1 implements OnInit{
constructor(private sharedService: SharedService) { }
ngOnInit() {
this.sharedService.sharedFunction();
}
}
component2:
import { SharedService } from '../shared.service';
import { Component, OnInit } from '#angular/core';
#Component({
selector: '.....',
templateUrl: '.......',
styleUrls: ['........']
})
export class Component2 implements OnInit{
constructor(private sharedService: SharedService) { }
ngOnInit() {
this.sharedService.sharedFunction();
}
}
Could be done using a service. For illustration purpose let's call it HeaderAndSidebarService:
Filename: header-and-sidebar.service.ts
#import { Injectable } from "#angular/core";
#Injectable()
export class HeaderAndSideBarService {
public testFunction() {
console.log('value');
}
}
To use the service, provide it within both header and sidebar component:
import { Component, OnInit, Input,ViewChild } from '#angular/core';
import { HeaderAndSideBarService } from "./header-and-sidebar.service";
#Component({
...,
providers: [HeaderAndSideBarService]
})
export class HeaderComponent {
constructor(private service: HeaderAndSideBarService ) { }
ngOnInit() {
this.service.testFunction();
}
}

updating variable in angular Service

I am new to angular and trying to update variable but I variable is not updating in view. I am accessing a variable "name" created in service and updating it but it isn't working. When I call clickme() the value of variable name doesn't update on the webpage and shows old value "no name". I want to change the variable name value to "rahul" and display it on the page.
my service:
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class FirstService {
name:string="no name"
setName() {
this.name="rahul"
}
}
code:
import { Component, OnInit } from '#angular/core';
import { FirstServiceService } from './first-service.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [FirstService]
})
export class AppComponent implements OnInit {
account:any
name:string
constructor(private userName:FirstService){ }
ngOnInit(): void {
this.name=this.userName.name
}
clickMe(e){
this.userName.setName()
}
}
You usually do with this way:
Service
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class FirstService {
private name:string="no name";
setName(_name: string): void {
this.name = _name;
}
getName(): string {
return this.name;
}
}
Component
import { Component, OnInit } from '#angular/core';
import { FirstService } from './first-service.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [FirstService]
})
export class AppComponent implements OnInit {
account:any
name:string
constructor(private firstService: FirstService){ }
ngOnInit(): void {
this.name=this.firstService.getName();
}
clickMe(e){
this.userName.setName("rahul");
this.name=this.firstService.getName();
}
}
Whereas I must admit that the value of name normally doesn't get set by the same method that afterwards consumes it from the service. At least not when these are the only 2 lines of code in the method, though. But I reckon you're still playing around a little with services and then it's okay.
There is no need to set the same variable name in service like component.You can use anything you want.
In App component
clickMe(e){
this.name=this.userName.setName();
}
In service
getName() {
return this.name;
}
I hope it will help
You only equals the variable "name" to this.userName.name in OnInit, this is the reason because you don't see any change -you're showing the variable "name", not the variable this.usuerName.Name.
Normally you can use some simple, it's a getter
You can write in component
export class AppComponent implements OnInit {
account:any
//NOT have a variable "name", just a getter
get name(){
return this.userName.name;
}
//even if you want you can write
set name(value)
{
this.userName.name=value;
}
constructor(private userName:FirstService){ }
ngOnInit(): void {
}
clickMe(e){
this.userName.setName()
//or this.name="George"; //if you include the function set name()
//or this.userName.name="George"
}
}

Categories

Resources