In my application their is some text which is coming from a constant file which is declared like this:
export const EmpStrings = {
data: "Welcome {{employee.name}}"
}
And In my component file there is an object called employee.
public employee = { name: 'xyz', dept: 'EE' }
Now In my HTML I want to use it like this:
<div class='e-data' [innerHTML] = "EmpStrings.data"></div>
But this didn't seems to be working.
I tried various variations:
[inner-html] = "EmpStrings.data"
[innerHTML] = {{EmpStrings.data}}
[innerHTML] = "{{EmpStrings.data}}"
But none of them seems to be working.
If you don't want to use JitCompiler then you can parse string yourself
component.ts
ngOnInit() {
this.html = EmpStrings.data.replace(/{{([^}}]+)?}}/g, ($1, $2) =>
$2.split('.').reduce((p, c) => p ? p[c] : '', this));
}
template
<div [innerHTML]="html"></div>
Plunker Example
use ${employee.name} to bind angular variable to innerHTML
"data": `Welcome ${employee.name}`
Angular doesn't interpolate strings like this, as far as I know one of the reason is security. The const doesn't have the context where your employee is in hence you see the error saying employee is not defined.
You could do this:
Change your constant:
export const EmpStrings = {data: "Welcome "};
then:
<div class='e-data'>{{EmpStrings.data}}{{employee.name}}</div>
But if for some reason you must use [innerHTML]:
In your component class, add a method:
getWelcomeMessage(){return EmpStrings.data + this.employee.name;}
in the component view:
<div class='e-data' [innerHTML] = "getWelcomeMessage()"></div>
Related
I'm trying to push another formbuilder within a formarray but it gives me an error since I think there are no items in the array when initializing the code, hence there are no controls. The error is Property 'controls' does not exist on type 'AbstractControl' after the
(<FormArray>this.loanTypeForm.controls['frequency']).controls[index]
I'm using angular 2.0.0-beta.17
let settingsForm: FormArray = new FormArray([]);
(<FormArray>this.loanTypeForm.controls['frequency']).push(
this.formBuilder.group({
'name': [value, Validators.required],
'settings': settingsForm,
})
);
(<FormArray>this.loanTypeForm.controls['frequency']).controls[index].controls['settings'].push(
this.formBuilder.group({
'term': [null, Validators.required],
'eir': [null, Validators.required],
})
);
You can use ['controls'] instead of .controls, as below:
(<FormArray>this.loanTypeForm.controls['frequency']).controls[index]['controls']['settings'].push(...)
But in order to simplify and provide more readability I'd suggest you to change it all to:
const control = this.loanTypeForm.get(`frequency.${index}.settings`) as FormArray;
control.push(...);
get() is the preferred way to access form controls
this.loanTypeForm.get(`frequency.${index}.settings`)
It seems that the loanTypeForm is treated as AbstractControl... so let's assure compiler that it is FormGroup
var group = this.loanTypeForm as FormGroup;
var array = group.controls['frequency'] as FormArray;
var control = group.controls[index]; // AbstractControl again.. could be casted as needed
and in case, that control is also group or form we just have to use assert (cast) as well
var control = group.controls[index] as FormGroup
And then we can easily continue
control.controls['settings']...
Here is My solution if you are Following the Angular Course on Udemy
This code will fail with the latest Angular version.
You can fix it easily though. Outsource the “get the controls” logic into a getter of your component code (the .ts file):
get controls() { // a getter!
return (<FormArray>this.recipeForm.get(‘ingredients’)).controls;
}
In the template, you can then use:
*ngFor="let ingredientCtrl of controls; let i = index"
This adjustment is required due to the way TS works and Angular parses your templates (it doesn't understand TS there)
below code is working
<FormArray>this.loanTypeForm.controls['frequency']).controls[index]['controls']['settings'].push(...)
sorry for the noob question. I created an http request and retrieved some pokemon data and put it in an object called pokemon, like so:
export class AppComponent implements OnInit{
title = 'Pokedex';
apiURL = 'https://pokeapi.co/api/v2/pokemon/1';
pokemon = {};
constructor(private http: HttpClient){}
ngOnInit(): void{
this.http.get(this.apiURL).subscribe(data =>{
const pokemon = {
name: data['name'],
id: data['id'],
abilities: data['abilities'].map( ability => ability['ability']['name']),
types: data['types'].map( type => type['type']['name']),
image: data['sprites']['front_default']
}
In the HTML, I tried to create an image with <img src = "{{ pokemon.image }}"/>
However, the only thing that appears is a broken image icon and this error apears:
GET http://localhost:4200/%7B%20pokemon.image%20%7D 404 (Not Found)
But when I console.log pokemon.image, the full URL is output to the console:
https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/1.png
What am I doing wrong here?
You can try it with this instead:
<img [src]="pokemon.image"/>
If this still not works, can you tell me what is the reflected value of that property in your HTML file?
<p>{{ pokemon.image }}</p>
I made two changes and its working :
1) pokemon:any; (instead of pokemon = {};)
2) this.pokemon (instead of const pokemon)
I have an issue with Observables in Angular 2
My component calls service function on Init like below:
delivery: IDeliveryCountry[];
ngOnInit() {
this.checkoutService._getInfo().subscribe(dev => this.delivery = dev);
}
This is how interface looks like IDeliveryCountry:
export interface IDeliveryCountry {
iso: string;
name: string;
}
This is how Service looks like:
_getInfo(): Observable<IDeliveryCountry[]> {
return this.http.get(this.deliveryCountryUrl)
.map((response: Response) => <IDeliveryCountry[]>response.json())
}
json file with data looks like this:
[
{
"iso":"se",
"name":"Sweden"
},
{
"iso":"dk",
"name":"Denmark"
}
]
My html file is just a simple ngFor loop:
<div *ngFor='let dev of delivery'>{{dev.iso}}</div>
So far all things works perfect, as expected I get back "se" and "dk" in UI.
The problem appears when I change a structure of data in my json file to following:
{
"country": {
"iso":"se",
"name":"Sweden"
}
}
I want data to only have one country with iso and name property for it. So my html file looks like following:
<div>{{delivery.iso}}</div>
But I am getting iso as undefined all the time
" Cannot read property 'iso' of undefined "
Thank you!
You should first of all use:
{{delivery.country.iso}}
The undefined error you are getting, is because the data is coming async, so use the safe navigation operator to avoid this:
{{delivery?.country?.iso}}
Demo
Optionally you could extract the data that is inside country, so you can shorten your code in your template from {{delivery?.country?.iso}} to just {{delivery?.iso}}, this can be done like so:
.map(res => res.json().country) // extract the data from the object country
You can just do this without ngFor since it is an Object
<div>{{delivery.country.iso}}</div>
After your comments, undefined is because the data is coming async, so use the elvis operator to avoid this:
{{delivery?.country?.iso}}
Alternatively you could change your service to return the DeliveryCountry[]
getInfo(): Observable<IDeliveryCountry[]> {
return this.http.get(this.deliveryCountryUrl)
.map((response: Response) => response.json())
.map(delivery => delivery.country);
}
Then:
ngOnInit() {
this.checkoutService.getInfo()
.subscribe(deliveryCountries => this.deliveryCountries = deliveryCountries);
}
Then:
<div *ngFor="let deliveryCountry of deliveryCountries">{{deliveryCountry?.iso}}</div>
I have a small expression to check whether 2 objects are different or not, in order to display this element (via adding class name):
<div ngClass='{{JSON.stringify(obj1) != JSON.stringify(obj2) ? "div-show" : ""}}'></div>
The problem is I get this error:
Cannot read property 'stringify' of undefined.
What I need a way to work around, or a proper solution if available. Thanks.
PS: I use JSON.stringify() to compare 2 simple objects, nothing fancy here.
Template code doesn't have access to all javascript, only component properties and methods. I think it would be best to create a 'stringify' method on your component, but you could just set a JSON property:
public constructor() {
this.JSON = JSON;
}
Also I think your expression is backwards. NgClass takes the css class as the property name and a true/false value to tell whether that class is on the element, and it needs to be in brackets:
<div [ngClass]="{'div-show': JSON.stringify(obj1) != JSON.stringify(obj2)}"></div>
2 Years later but, you can do it the Angular Way using the built in pipe 'JsonPipe' from #angular/common
#Component({
selector: 'json-pipe',
template: `<div>
<p>Without JSON pipe:</p>
<pre>{{object}}</pre>
<p>With JSON pipe:</p>
<pre>{{object | json}}</pre>
</div>`
})
export class JsonPipeComponent {
object: Object = {foo: 'bar', baz: 'qux', nested: {xyz: 3, numbers: [1, 2, 3, 4, 5]}};
}
you can achieve it like this in your component do this.
myjson:any=JSON;
and in you view do it like this
<div ngClass='{{myjson.stringify(obj1) != myjson.stringify(obj2) ? "div-show" : ""}}'></div>
I am trying to use Angucomplete-alt -
autocomplete directive for AngularJS without any luck.
Problem is: selected value from autocomplete list does not update my model.
In Angular application
var app = angular.module("workScheme2App", ['angucomplete-alt']);
workScheme2App.controller('SMSController', function ($scope, $http) {
this.anketa =
{
DeliveryAddress_Province: {
id: 0,
name: ""
}
};
};
In view:
<angucomplete-alt id="DeliveryAddress_Province" name="DeliveryAddress_Province"
pause="400"
selectedObject="anketa.DeliveryAddress_Province"
remote-url="../../Client/getListProvince?query="
title-field="name"
/>
remote-url="../../Client/getListProvince?query="
MVC controller method in "remote-url" attribute successfully returns JSON array of objects like this:
[{id: 1, name: "Киевская"}, {id:2, name: "Одесская"}]
Dropdown appears and I can select needed value, but after selection exception happened:
Error: [$compile:nonassign] Expression 'undefined' used with directive 'angucompleteAlt' is non-assignable!
http://errors.angularjs.org/1.3.11/$compile/nonassign?p0=undefined&p1=angucompleteAlt
at REGEX_STRING_REGEXP (angular.js:63)
at $get.parentSet (angular.js:7658)
at parentValueWatch (angular.js:7671)
at Object.regularInterceptedExpression (angular.js:12838)
at Scope.$get.Scope.$digest (angular.js:14222)
at Scope.$get.Scope.$apply (angular.js:14493)
at HTMLDivElement. (angular.js:21427)
at HTMLDivElement.p.event.dispatch (jquery.js:2)
at HTMLDivElement.p.event.add.g.handle.h (jquery.js:2)
I cant figure out how to assign selected to anketa.DeliveryAddress_Province object ? Can anyone help please?
The problem was in attribute "selectedObject", after i change it to "selected-object" it works properly. Hyphenated attributes transforms in directive to camelCase properties.