Value undefined after a function - javascript

I have one class with one fuction in it, and another class that will import the first class and use that function. After the function operates i need one value, but i am not getting any value afte the function.
First class:
export class MoveEff {
checkEffect(effectFaceOff1,moveEff1,moveEff2){
if ( effectFaceOff1=== 'grassgrass') {
moveEff1 = 10;
console.log(moveEff1);
}
}
}
Second class :
import { Component, OnInit } from '#angular/core';
import {GenIService} from "../Pokemons/gen-i.service";
import {MovesService} from "../Moves/moves.service";
import {MoveDataClass} from "../MoveDATA/move-data-class";
import {MoveEff} from "../MoveDATA/move-eff";
#Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage implements OnInit {
effectFaceOff1;
moveEff1;
moveEff2;
constructor(private moveeff: MoveEff) {}
this.moveeff.checkEffect(this.effectFaceOff1,this.moveEff1,this.moveEff2);
console.log(this.moveEff1,this.moveEff2);
On the last console.log i should be seeing the 10 value of moveEff1, but it appears undefined.
Why? and how can i solve it?

Exporting the class may not be enough. Try exporting and importing all your methods as modules, or exporting the method directly.

i don't know where you are getting effectFaceOff1, moveEff1 and moveEff2 from, but if they are #Input, their values cannot be retrieved in the constructor.
In that case, you should move your code to the ngOnInit:
ngOnInit() {
this.moveeff.checkEffect(this.effectFaceOff1,this.moveEff1,this.moveEff2);
console.log(this.moveEff1,this.moveEff2);
}
Last but not least, MoveEff should be made an Injectable in order to provide it to your class:
#Injectable({ providedIn: 'root' })
export class MoveEff {
checkEffect(effectFaceOff1,moveEff1,moveEff2){
if ( effectFaceOff1 === 'grassgrass') {
moveEff1 = 10;
console.log(moveEff1);
}
}
}

Related

Angular - trying to use child component function in parent view but I'm gettting an error

When I use #ViewChild I get the error that the component is not defined.
When I use #ViewChildren I get the error that the function from that component is not a function.
I am new to using child components in Angular so I'm not sure why it's doing this when I do have the child component defined in the parent component and when it's clearly a function in the child component.
I don't want to have to define every function from the child in the parent or else what's even the point of using a separate component.
Child Component
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-mood',
templateUrl: './mood.component.html',
styleUrls: ['./mood.component.css']
})
export class MoodComponent implements OnInit {
moodColors = ['red', 'orange', 'grey', 'yellow', 'green'];
constructor() { }
ngOnInit(): void {
}
chooseMood() {
alert(this.moodColors);
}
}
Parent Component (Relavant Part of Version with "ERROR TypeError: ctx_r3.mood is undefined")
import { Component, OnInit, ViewChild, ViewChildren } from '#angular/core';
import { ViewEncapsulation } from '#angular/core';
import { MoodComponent } from '../mood/mood.component';
#Component({
selector: 'app-calendar',
templateUrl: './calendar.component.html',
styleUrls: ['./calendar.component.css'],
encapsulation: ViewEncapsulation.None
})
export class CalendarComponent implements OnInit {
#ViewChild('mood') mood: MoodComponent = new MoodComponent;
Parent Component (Relavant Part of Version with "ERROR TypeError: ctx_r3.mood.chooseMood is not a function")
import { Component, OnInit, ViewChild, ViewChildren } from '#angular/core';
import { ViewEncapsulation } from '#angular/core';
import { MoodComponent } from '../mood/mood.component';
#Component({
selector: 'app-calendar',
templateUrl: './calendar.component.html',
styleUrls: ['./calendar.component.css'],
encapsulation: ViewEncapsulation.None
})
export class CalendarComponent implements OnInit {
#ViewChildren('mood') mood: MoodComponent = new MoodComponent;
Parent View
<h2 (click)="mood.chooseMood()"></h2>
You don't explicitly initialize view children via new.
Just use:
#ViewChild('mood') mood : MoodComponent;
If that doesn't work post a Stackblitz example which I can edit to resolve the issue.
Also, using ViewChild is more of an exception in Angular, and your use of it points to a probable design issue. More likely you child component should emit via an Output to the parent.
Regarding outputs, you can do something like this - though it is hard to give a precise answer without deeper knowledge of what you are trying to achieve:
export class MoodComponent implements OnInit {
#Input() moodId: string;
#Output() chooseMood = new EventEmitter<string>();
moodClicked(){
this.chooseMood.emit(moodId);
}
}
export class CalendarComponent implements OnInit {
moodChosen(string: moodId){
console.log(moodId);
}
}
// Calendar template:
<app-mood
moodId="happy"
(chooseMood)="moodChosen($event)"
></app-mood>
1 - you have to use this code
#ViewChild('mood') mood : MoodComponent;
when you are using #ViewChildren it will return list of items with the 'mood' name then you have to use this code
mood.first.chooseMood() ;
its better use ViewChildren when there is ngIf in your element
2- no need new keyword for initialize mood variable
it would be fill after ngOnInit life cycle fires

Problem calling one Angular component from another component

At work, I have run into a problem using Angular. I have this kind of Angular component:
#Component({
selector: 'foo',
templateUrl: 'foo.html'
})
export class FooComponent {
#Input() data: string;
content: string;
ngOnInit() {
this.content = this.data;
}
setValue(data) {
this.content = data;
}
}
This is initialized from my main Angular component in a code block such as this:
this.components = [FooComponent, BarComponent, BazComponent, QuuxComponent];
Now this works so far. But if I try to call the setValue() function with this.components[0].setValue("Hello world!"); I get an error "this.components[0].setValue is not a function."
What is the reason for this and how can I fix it?
This seems like a very very weird way to work with components in angular.
You really don't want to break encapsulation by calling methods inside one component from another component.
I personally haven't seen this kind of component referencing anywhere (and have doubts it is a correct approach).
There is no reason to duplicate the data property in the content.
You can pass values in the template. Or use a service if you don't have direct access to the template.
Here is a very basic example on how to modify data from the parent using a template and #Input.
app.component.ts
import { Component } from "#angular/core";
#Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
message = "I am a message from the parent";
}
app.component.html
<app-child [content]='message'></app-child>
child.component.ts
import { Component, OnInit, Input } from "#angular/core";
#Component({
selector: "app-child",
templateUrl: "./child.component.html",
styleUrls: ["./child.component.css"]
})
export class ChildComponent implements OnInit {
#Input("content") public content: string;
constructor() {}
ngOnInit() {}
}
child.component.html
<p>{{content}}</p>

Why does this variable always return null ? Angular Service

Its now 8 hours trying to solve a trivial issue & I can't believe it !
here below a script of angular service
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class GetStockDataService {
constructor(public http:HttpClient) { }
RequestData={"query":"{\n stock{\n history{\n \n low\n high\n demand\n }\n }\n}"}
getstockdata(){
return this.http.post('http://localhost:3000/',this.RequestData)
}
}
and here is a component script which is calling that service
import { Component, OnInit } from '#angular/core';
import { GetStockDataService } from '../services/get-stock-data.service';
import { Platform } from '#ionic/angular';
#Component({
selector: 'app-Stocks',
templateUrl: 'Stocks.page.html',
styleUrls: ['Stocks.page.scss']
})
export class StocksPage implements OnInit {
constructor(private GetStockData:GetStockDataService , private platform : Platform) {}
res:any
ngOnInit(){
this.getdata().subscribe(data=>{this.res=data});
console.log(this.res)
}
getdata(){
return this.GetStockData.getstockdata() }}
WHY the "res" variable is always returning NULL ????
knowing that when I put the console log the variable inside there in the function in the subscription part .. it returns data
but I can't make this variable global ... how could I do that ? I just want to get the data from the subscription to the "res" variable to use it the HTML file later .
Due to Async call, console.log(this.res) executes before server call is processed.
Change
this.getdata().subscribe(data=>
{
this.res=data
});
console.log(this.res)
To
this.getdata().subscribe(data=>
{
this.res=data;
console.log(this.res)
});

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

Access angular component meta-data

is it possible to get the value of e.g. changeDetection attribute defined as part of a given component's decoration?
import { Component, ChangeDetectionStrategy } from '#angular/core';
#Component({
selector: 'app-banner',
template: '<h1>{{title}}</h1>',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class BannerComponent { }
i've tried:
Reflect.getMetadataKeys(BannerComponent) // []
Reflect.getOwnMetadataKeys(BannerComponent) // []
Reflect.getMetadata('annotations', BannerComponent) // undefined
https://plnkr.co/edit/VXfcZH9BWPWbdyBOJRTV?p=preview
Seemingly hacky but nevertherless a solution:
BannerComponent['__annotations__'][0]
https://plnkr.co/edit/HAbomBljAACHVz6N33m5?p=preview
Credits this SO answer.

Categories

Resources