Image does not show up with Angular ngx-translate - javascript

I am using ngx-translate with Angular. I want to change an image depending on the language used in the application. The thing is that I canĀ“t change the image when I click a language. I have two languages 'en' and 'es'.
This is my 'header.component.html'. This is the component which has the menu of the application.
As you can see there is an 'updateSrc()' function in the click attribute.
<div class="select-box__current" tabindex="1">
<div class="select-box__value" (click)="useLanguage('es');updateSrc(second_url);">
<input class="select-box__input" type="radio" id="0" value="1" />
<p class="select-box__input-text">es</p>
</div>
<div class="select-box__value" (click)="useLanguage('en');updateSrc(first_url);">
<input class="select-box__input" type="radio" id="1" value="2" checked="checked"/>
<p class="select-box__input-text">en</p>
</div>
</div>
Also I have another component 'looker.component.html' where the image have to change.
<div class="map">
<img class="graph" src="{{first_url}}" alt="graph">
</div>
And this is my 'looker.component.ts' where I am not sure how to write the updateSrc() function in order to change the other URL when someone clicks one of the two languages.
import { Component, OnInit, PLATFORM_ID, Inject } from '#angular/core';
import { Meta, Title } from '#angular/platform-browser';
#Component({
selector: 'app-looker',
templateUrl: './looker.component.html',
styleUrls: ['./looker.component.scss']
})
export class LookerComponent implements OnInit {
first_url: string = "https://storage.googleapis.com/amarello-web-assets/img/graph_2.svg";
second_url: string = "https://storage.googleapis.com/amarello-web-assets/img/graph_1.svg";
constructor(
private title: Title,
private meta: Meta,
#Inject(PLATFORM_ID) private platformId: Object
) { }
ngOnInit(): void {
this.first_url;
}
updateSrc(url) {
}
}

You can use property binding on [src] which will take the value of the property first_url then on the change event just update the property as shown below!
html
<div class="map">
<img class="graph" [src]="first_url" alt="graph"> <!-- changed here -->
</div>
ts
import { Component, OnInit, PLATFORM_ID, Inject } from '#angular/core';
import { Meta, Title } from '#angular/platform-browser';
#Component({
selector: 'app-looker',
templateUrl: './looker.component.html',
styleUrls: ['./looker.component.scss']
})
export class LookerComponent implements OnInit {
first_url: string = "https://storage.googleapis.com/amarello-web-assets/img/graph_2.svg";
second_url: string = "https://storage.googleapis.com/amarello-web-assets/img/graph_1.svg";
constructor(
private title: Title,
private meta: Meta,
#Inject(PLATFORM_ID) private platformId: Object
) { }
ngOnInit(): void {
}
updateSrc(url) {
this.first_url = url; // <- changed here
}
}

Related

Angular passing data to child component

Hey I am trying to display a simple error message on my login page if the login fails. Following is my login.component.html:
<div class="container shadow login-container">
<div class="row">
<div class="col-sm-12 text-center">
<div class="error-message">
<app-server-error [errorMessage]="error" ></app-server-error> -----> not displaying on screen
</div>
<div class="login-form-container">
<div class="login-input-container">
<input [(ngModel)]="user.email" type="email" placeholder="Enter your email" class="buddha-input"/>
</div>
<div class="login-input-container">
<input [(ngModel)]="user.password" type="password" placeholder="Enter password" class="buddha-input"/>
</div>
<div class="login-input-container">
<button (click)="tryLogin()" class="login-form-button">Login</button>
</div>
</div>
</div>
</div>
</div>
Following is my server-error.component.html:
<p>
{{errorMessage}}
</p>
Following is my server-error.component.ts
import { Component, OnInit, Input } from '#angular/core';
#Component({
selector: 'app-server-error',
templateUrl: './server-error.component.html',
styleUrls: ['./server-error.component.css']
})
export class ServerErrorComponent implements OnInit {
#Input() public errorMessage: string;
constructor() { }
ngOnInit() {
}
}
"Error" is not showing up on the screen and I am not getting errors on console either. Please do let me know how I can fix this? Thank you
#Input() public errorMessage: string; expects error to be a string.
Define error like this in .ts
error = 'error message'
Working Demo
With [errorMessage]="error", error should be a variable.
So you need to define it in your component.
But if you want to display the string "error",
then pass it like this [errorMessage]="'error'" or errorMessage="error"
The other posted answer may solve your problem but I would go with Service which will be responsible for showing an error from everywhere in the Application and also you can have a full control on the error component as it is centralized at a one place:
error.service:
import { Injectable } from '#angular/core';
import { BehaviorSubject } from 'rxjs';
#Injectable()
export class ErrorService {
constructor() { }
private errorMessages = new BehaviorSubject('');
errorMessage = this.errorMessages.asObservable();
showError(message: string) {
this.errorMessages.next(message)
}
}
Error.Component.ts:
import { Component, OnInit, Input } from '#angular/core';
import {ErrorService } from "../error.service";
#Component({
selector: 'app-server-error',
templateUrl: './server-error.component.html',
styleUrls: ['./server-error.component.css']
})
export class ServerErrorComponent implements OnInit {
private errorMessage : any;
constructor(public errorService : ErrorService) { }
ngOnInit() {
this.errorService.errorMessage.subscribe(value => {
this.errorMessage = value;
})
}
}
App.Component.html:
// show it in app.component
<div class="error-message">
<app-server-error></app-server-error>
</div>
Use (in Login Component):
import { Component, OnInit } from "#angular/core";
import {ErrorService } from "../error.service";
#Component({
selector: "app-login",
templateUrl: "./login.component.html",
styleUrls: ["./login.component.css"]
})
export class LoginComponent implements OnInit {
constructor(public errorService: ErrorService) {}
user = {};
ngOnInit() {}
tryLogin(){
this.errorService.showError('An error');
}
}

Pass boolean to another Angular component

I have two Angular components
results.table and results.query
I want to hide the table inside the results.table.component when the user clicks on the reset button within the results.query.component
Maybe I am doing this wrong with event emitter, or maybe there is a better way to do this
results.table HTML
<div *ngIf='results?.length>0'>
<table *ngIf="showResults" class='table'>
<tr>
<th>Result Name</th>
<th>Location</th>
</tr>
<tbody>
<ng-template ngFor let-results [ngForOf]='items' let-i="index">
<tr>
<td>
<span>{{result?.description}}</span>
</td>
<td>
<span>{{result?.location}}</span>
</td>
</tr>
</ng-template>
</tbody>
</table>
</div>
results.table TS
showResults: boolean = true;
showResults(event) {
console.log('this is not getting called')
if (event) {
this.showResults = false;
}
}
results.query HTML
<div class="panel-body">
<form (submit)="onSubmitClicked()">
<div class="row">
<div class="form-group col-md-12 col-xs-12">
<div class="col-xs-12 col-sm-3 col-md-3 col-lg-3">
<label class="col-md-12 col-xs-12 control-label no-margin no-padding">Location: </label>
<pg-radio-toggle-select class="col-md-12 col-xs-12 no-margin no-padding" name="locationChangeInput" [(ngModel)]="Location"
(selectedChanged)="onFilteringLocation($event)" [options]='locationOptions'>
</pg-radio-toggle-select>
</div>
<pg-inputfield name="description" class="col-xs-12 col-sm-3 col-md-3 col-lg-3" [(ngModel)]="paramsModel.description"
displaytext="Name:"></pg-inputfield>
</div>
</div>
<div>
<button type="reset" class="btnReset" (click)="reset()">Reset</button>
<button type="submit" name="btnSearch">Search</button>
</div>
</form>
</div>
results.query TS
import {Component, OnInit, EventEmitter, Output} from '#angular/core';
import * as _ from 'lodash';
import { LocationService } from '../location-service.service';
#Component({
selector: 'result-query',
templateUrl: './result-query.component.html',
styleUrls: ['./result-query.component.less'],
})
export class ResultQueryComponent implements OnInit {
#Output() showResults: EventEmitter<boolean> = new EventEmitter<boolean>();
constructor(
private LocationService: LocationService,
) {
this.reset();
}
ngOnInit() {
this.reset();
}
onSubmitClicked() {
console.log('test')
}
reset(): void {
console.log('I am the reset king');
this.showResults = false;
this.showResults.emit(true);
this.onSubmitClicked();
}
}
If two components does have a parent child relationship, you can use #Input() #Output() decorators.
4 Ways to share data between angular components
Component Interaction
Input Output Example
Parent Component
import { Component, OnInit, ViewEncapsulation } from '#angular/core';
import { Stephen } from '../stephen.model';
#Component({
selector: 'app-parent',
template: `
Hello, Mr. (or Ms.): {{ selectedName }}
`,
styleUrls: ['./parent.component.css'],
encapsulation: ViewEncapsulation.None
})
export class ParentComponent implements OnInit {
stephen: Stephen;
selectedName: string;
constructor() {
this.stephen = new Stephen();
this.selectedName = this.stephen.firstName;
}
ngOnInit() {
}
updateName(selectedName: string): void {
console.log('in parent');
this.selectedName = selectedName;
}
}
Child Component
import { Component, OnInit, ViewEncapsulation, Input, Output, EventEmitter } from '#angular/core';
import { Stephen } from '../../stephen.model';
#Component({
selector: 'app-child',
template: `
{{ stephen.firstName }}
{{ stephen.lastName }}
{{ stephen.fullName }}
`,
styleUrls: ['./child.component.css'],
encapsulation: ViewEncapsulation.None
})
export class ChildComponent implements OnInit {
#Input() stephen: Stephen;
#Output() onNameSelected: EventEmitter;
constructor() {
this.onNameSelected = new EventEmitter();
}
ngOnInit() {
}
clicked(name: string): void {
this.onNameSelected.emit(name);
}
}
Important - second solution
But in your case these 2 components don't seem to have a parent child relationship. If you want to share data between two components, you can create a share-able service. This service will contain and EventEmitter to which a component that needs latest change will subscribe in ngOnInit method and the component which will have latest data will call a function from this share-able service to emit that event.
share-able service
import { Injectable, Output, EventEmitter } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class MessengerService {
#Output() change: EventEmitter<any> = new EventEmitter();
sendData(data: any): any {
this.change.emit(data);
}
}
The component that want to know about this change will subscribe to this event in it the ngOnInit like this.
messengerService.change.subscribe(emitedValue => {
this.value = emitedValue;
});
The component that has the new change will call the sendData method is messenge / share-able service to post new data to the event subscribers whenever it is required.
I dont know if you forgot to write it in your question, but you should have a results.query Tag in your results.Table HTML, and call the output through it. Considering your selector is app-results-query, it would be like this:
results.table HTML
<app-results-query (showResults)="changeShowResults($event)"></app-results-query>
<table *ngIf="showResults">
//table stuff
</table>
results.table TS
showResults: boolean = true;
changeShowResults(event: boolean) {
console.log('this is not getting called')
if (event) {
this.showResults = false;
}
}

Angular 5 passing object to a component

So i have created the following class:
export class PresentObject {
public type: string;
public resourceUrl: string;
public text: string;
}
And the following component:
import {Component, Input, OnInit} from '#angular/core';
import {PresentObject} from '../classes/present-object';
#Component({
selector: 'app-video',
templateUrl: './video.component.html',
styleUrls: ['./video.component.css']
})
export class VideoComponent implements OnInit {
#Input()
view: PresentObject;
constructor() {
}
ngOnInit() {
console.log(this.view.text);
}
}
Now I attempt to insert that through HTML:
<section *ngFor="let view of views; let last = last" [ngSwitch]="view.type">
<app-video *ngSwitchCase="'video'" view="{{view}}"></app-video>
<span *ngIf="last">{{repeatComplete()}}</span>
</section>
After debugging I can see if I console.log(this.view) i get: "[object Object]"
Can anyone tell me what I've done wrong?
<section *ngFor="let view of views; let last = last" [ngSwitch]="view.type">
<app-video *ngSwitchCase="'video'" view="view"></app-video>
<span *ngIf="last" (click)="repeatComplete()">LAST</span>
</section>

html wont render from inside angular 2 component

I'm using a service to dynamically change the content in my header depending on the page I'm on, however when I put HTML in my component it doesn't render in the browser (see example below)
home.component.ts
import { Component, OnInit } from '#angular/core';
import { HeaderTitleService } from '../../services/headerTitle.service';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
constructor(
private headerTitleService: HeaderTitleService
) { }
ngOnInit() {
this.headerTitleService.setTitle(`
We strive to create things
<br> that are engaging, progressive
<br> & above all
<span class="highlight">
<em>innovative.</em>
</span>
`);
}
}
header.component.ts
import { Component, OnInit } from '#angular/core';
import { HeaderTitleService } from '../../../services/headerTitle.service'
#Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss']
})
export class HeaderComponent implements OnInit {
title: any;
constructor(
private headerTitleService: HeaderTitleService
) { }
ngOnInit() {
this.headerTitleService.title.subscribe(updatedTitle => {
this.title = updatedTitle;
});
}
}
header.component.html
<h1>{{title}}</h1>
so Im trying to set the title to be a string that has html tags in it that I want to be rendered but what happens is the whole thing comes out as a string instead of how it would look like it I had put it in my home.component.html.
Is there a way I can do this??
You can set the [innerHtml] property
<h1 [innerHtml]="title"></h1>
Example

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

Categories

Resources