Reputation: 317
I created an attribute directive to display the logo of network based on a series of numbers entered. However, I cannot get my HTML page to display anything. My project compiles, but the HTML page shows as blank. What did I do wrong?
Below is my code for the app.component.html:
<input type="text"[(ngModel)]="cardNumberInput"/>
<p>{{cardNumberInput}}</p>
<img applogo [cardType]="cardNumberInput" width="30"/>
Below is my code for app.module.ts:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms'
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LogoDirective } from './logo.directive';
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
LogoDirective
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
directive.ts:
import {Directive, Input, OnChanges, HostBinding} from '@angular/core';
enum CardType { VISA = 'visa', MASTERCARD = 'mastercard', AMERICAN_EXPRESS = 'aexpress', DISCOVER = 'discover', DINERS = 'diners', UNKNOWN = 'unknown'}
@Directive({
selector: '[logo]'
})
export class LogoDirective implements OnChanges {
@HostBinding('src')
imageSource;
@Input()
cardNumber: string;
ngOnChanges() {
this.imageSource = 'assets/cards' + this.getCardTypeFromNumber() + '.png';
}
getCardTypeFromNumber(): CardType {
if (this.cardNumber) {
if (this.cardNumber.startsWith('34')) {
return CardType.AMERICAN_EXPRESS;
} else if (this.cardNumber.startsWith('4')) {
return CardType.VISA;
} else if (this.cardNumber.startsWith('5')) {
return CardType.MASTERCARD;
} else if (this.cardNumber.startsWith('60')) {
return CardType.DISCOVER;
} else if (this.cardNumber.startsWith('30')) {
return CardType.DINERS;
}
}
return CardType.UNKNOWN;
}
}
directive.spec.ts:
import { LogoDirective } from './logo.directive';
describe('LogoDirective', () => {
it('should create an instance', () => {
const directive = new LogoDirective();
expect(directive).toBeTruthy();
});
});
Upvotes: 1
Views: 144
Reputation: 8301
There are couple of mistakes in your attribute binding. Please rectify your template as below:
Changes Needed
constructor(private element: ElementRef){
}
ngOnChanges() {
debugger;
this.imageSource = 'assets/cards' + this.getCardTypeFromNumber() + '.png';
this.element.nativeElement.src = this.imageSource;
this.element.nativeElement.alt = this.imageSource;
}
<input type="text"[(ngModel)]="cardNumberInput"/>
<p>{{cardNumberInput}}</p>
<img logo [cardNumber]="cardNumberInput" width="30" />
logo.directive.ts
import {Directive, Input, OnChanges, HostBinding, ElementRef} from '@angular/core';
enum CardType { VISA = 'visa', MASTERCARD = 'mastercard', AMERICAN_EXPRESS = 'aexpress', DISCOVER = 'discover', DINERS = 'diners', UNKNOWN = 'unknown'}
@Directive({
selector: '[logo]'
})
export class LogoDirective implements OnChanges {
imageSource:string ='';
@Input()
cardNumber: string;
constructor(private element: ElementRef){
}
ngOnChanges() {
debugger;
this.imageSource = 'assets/cards' + this.getCardTypeFromNumber() + '.png';
this.element.nativeElement.src = this.imageSource;
this.element.nativeElement.alt = this.imageSource;
}
getCardTypeFromNumber(): CardType {
if (this.cardNumber) {
if (this.cardNumber.startsWith('34')) {
return CardType.AMERICAN_EXPRESS;
} else if (this.cardNumber.startsWith('4')) {
return CardType.VISA;
} else if (this.cardNumber.startsWith('5')) {
return CardType.MASTERCARD;
} else if (this.cardNumber.startsWith('60')) {
return CardType.DISCOVER;
} else if (this.cardNumber.startsWith('30')) {
return CardType.DINERS;
}
}
return CardType.UNKNOWN;
}
}
<input type="text"[(ngModel)]="cardNumberInput"/>
<p>{{cardNumberInput}}</p>
<img logo [cardNumber]="cardNumberInput" width="30" />
you can see this working stackblitz - https://stackblitz.com/edit/angular-4bd23d It is showing the alt attributes as i don't have the images.
I hope it will help.
Upvotes: 2