Angular v6 Elements #Input() For Initial Binding Not Working - angular6

I have created a custom element and placed on a page like this:
<my-custom-element [value]="100"></my-custom-element>
In the component definition, I have this:
#Input() value: number = 50;
At run-time, the value is always 50. I expect it to be 100. If I remove the default, value is undefined. What am I missing?
Thanks!!

In NG Elements you may not find in your OnIt but in OnChanges.
Please add below line and check it is defined.
public ngOnChanges(): void {
console.log('on changes value: ', this.value);
}

You can set data using HTML attributes and to change/update data in Angular Elements you have to use vanilla js, query selector and assign data like below
custom element tag with initial value = 0
<my-custom-element value="0" ></my-custom-element>
select custom element through the query selector and assign value.
var customElement = document.querySelector('my-custom-element');
customElement.value = 100;

Related

How can I change the html img element source witch dart?

I have this img element in my HTML project:
<img id="themeToggle" src="./images/moon.svg">
and i want to change the source of this element to be "./images/sun.svg".
I tried with:
void main() {
var themeToggleButton = querySelector('#themeToggle');
themeToggleButton?.onClick.listen((event) {
themeToggleButton.dataset['src'] = './images/sun.svg';
});
}
since the .dataset attribute is the only one that lets you to access the selected element's attributes, but it does not work. Any suggestion, please?
You should be able to use the .attributes getter to get the attributes Map and set there the value:
themeToggleButton?.attributes['src'] = './images/sun.svg'
Note: .dataset (as specified in the docs) is used only for the element properties that start with data-

Angular 10 | Add class name as variable to ngClass

I have 20+ elements, which all should use the same class (animate.css)
It is super annoying to change all classes if I want to edit the animation, so I saved the animation class in my service in a variable:
animClassSecond = "animate__animated animate__bounceInUp";
But I cant figure out how to add it to [ngClass], this does not work:
[ngClass]="{'select_elem':true, 'btn_2':true, 'dataService.animClassSecond':true}"
[ngClass]="{'select_elem':true, 'btn_2':true, 'this.dataService.animClassSecond':true}"
[ngClass]="{'select_elem':true, 'btn_2':true, this.dataService.animClassSecond:true}"
[ngClass]="{'select_elem':true, 'btn_2':true, dataService.animClassSecond:true}"
Its either a template error or it does not resolve to the variable. Any ideas?
P.S.: Adding a second [ngClass] attribute also does not work, because the first one is ignored.
is:
[ngClass]="dataService.animClassSecond"
But remember that you need declare the service public in the constructor
constructor(public dataService:DataService){}
NOTE you can use class and [ngClass] in the same tag:
class="select_elem btn_2" [ngClass]="dataService.animClassSecond"
This is probably not achievable in the template since the Angular template language is quite limited.
Just move the logic of ngClass object into your component.ts. There you can use all TypeScript's power
ngOnInit() {
this.ngClassObj = { [dataService.animClassSecond]: true };
}
or if you need it to be dynamic (use this one carefully because it might become a performance issue)
get ngClassObj() {
return { [dataService.animClassSecond]: true };
}
and then
[ngClass]="ngClassObj"

Polymer 2.0 :Please Explain the how the Observer method is working in this code?

This is the code snippet but I'm not able to understand how the observer method is working
static get properties() {
return {
selected: {
type: Object,
observer: '_selectedChanged'
}
};
}
_selectedChanged(selected, oldSelected) {
if (oldSelected) oldSelected.removeAttribute('selected');
if (selected) selected.setAttribute('selected', '');
}
connectedCallback() {
super.connectedCallback();
this.selected = this.firstElementChild;
}
full code: https://codelabs.developers.google.com/codelabs/polymer-2-carousel/index.html?index=..%2F..%2Findex#3
What is selected and oldselected and how can we do oldSelected.removerAttribute?
Are these objects of elements?
Please elaborate!
selected is property of element. It's value is some HTML element (in this case it's always img i think) so, in selected property there is always saved reference to img somewhere in html. When this property change, function _selectedChanged is called with 2 arguments. first argument is new image that is currently saved in selected and second argument is old image(previous value of selected).
further in tutorial you can see code
const elem = this.selected.nextElementSibling;
if (elem) {
this.selected = elem;
}
where is shown that const elem takes some html element and put it into this.selected.
So inside function _selectedChanged they removed html attribute from old image that was previously selected (so it was visible on screen) and added new html attribute to new image that should be visible on screen for now.
You can imagine that img with attribute selected is the only one that is shown on the screen at the time
I hope you understand my explanation. My english isn't 100% so if you have question, ask me and i can try to explain it more.
EDIT
Some example with binding and observer:
Let's say we have some paper-input which should show some results (articles for example) based on value of this input. So we have some HTML:
<paper-input value="{{search}}" label="Find articles"></paper-input>
this is primitive. Just some paper-input with value stored in search property. inside script tag:
Polymer({
is: 'test-el',
properties: {
search: {
type: String,
observer: "_findResults"
},
articles: {
type: Array
}
},
_findResults() {
this.set("articles", ['firstArticle', 'secondArticle', Math.random()]);
},
});
Explain: we defined property search and articles. Whenever property search changes, it calls function _findResults (because of observer). Function _findResults do only one thing. this.set("articles") is almost same as this.articles =. More about this can be found in documentation. So this.set("articles", ['firstArticle', 'secondArticle', Math.random()]); means it creates array and set it to articles property. and now, when we have some array that is changing everytime user enter some value in paper-input, we can add some HTML to show these articles:
<template is="dom-repeat" items="{{articles}}" as="item">
[[item]] <br>
</template>
I made also fiddle, so you can play with it and understand it a little bit more.
https://jsfiddle.net/2va41sy0/1/
Your question at the beginning was almost same in difference that they stored in some property reference to HTML object and not only just string. This is also about understand some basics of javascript and not polymer

How make a part of CSS class dynamic and send value to it?

I have some links in Header of my mvc project that has a styling which shows an icon by a link and add vale inside it. for example consider this code:
<span class="icon-alert-13"></span>
<span class="icon-docs"></span>documents
This is how it looks like:
I have this working with all the numbers for example if I change 13 to 18 like :icon-alert-18 it shows 18 in the icon.
This is style:
.icon-alert-18:before {
content: '\0030';
}
How I can make number part of class="icon-alert-18" as variable so I can pass value from my code and get the icon populated with the value I pass?
Also this is in Mobile development.
Let's say you have a variable called alertNumber and it holds the number you want to display in your icon.
You can fetch your icon with any of the DOM functions:
const numbersIcon = document.getElementById("numbersIcon");
Declare classes that you always want your element to have, for example:
const defaultNumbersIconClasses = "foo";
You can pass that variable to a function that changes the class of the elements like this:
function updateIconTo(number) {
numbersIcon.className = defaultNumbersIconClasses;
numbersIcon.classList.add("icon-alert-" + number);
}
The first line inside the function sets the classes of the element to the default classes you have specified.
The second one adds icon-alert- plus your number as a new class.
You can now use that function on whatever type of event you like, for example, an onclick event:
<span onclick="updateIconTo(alertNumber)" id="numbersIcon" class="icon-alert-13"></span>
Hope that helped!

Create Html local variable programmatically with Angular2

I need to know if there is a way to create HTML local variables programmatically.
I am developing a web app where I have an NgFor loop and I want to be able to assign a local variable to each sub element created by the NgFor.
ie :
<div *ngFor="#elt of eltList" >
<span #setLocalVariable(elt.title)></span>
</div>
setLocalVariable(_title : string){
let var = do some stuff to _title;
return var;
}
The exemple above shows you what I am trying to accomplish and obviously does not work.
Is there a way to achieve this ?
Thank you in advance.
Edit:
After seeing the answers I got (and i thank everyone who took the time to read my question and tried to answer it) i'll explain a bit more why i want it that way.
I will be using : loadIntoLocation() from the DynamicComponentLoader.
That function got as a 3rd parameter a string that refers to an anchors (ie : #test in an html element). Thats why i need to create those local variables with a name equal to the one of my elt.title.
I think local variables (defined with the # character) don't apply for your use case.
In fact, when you define a local variable on an HTML element it corresponds to the component if any. When there is no component on the element, the variable refers to the element itself.
Specifying a value for a local variable allows you to select a specific directive associated with the current element. For example:
<input #name="ngForm" ngControl="name" [(ngModel)]="company.name"/>
will set the instance of the ngForm directive associated with the current in the name variable.
So local variables don't target what you want, i.e. setting a value created for the current element of a loop.
If you try to do something like that:
<div *ngFor="#elt of eltList" >
<span #localVariable="elt.title"></span>
{{localVariable}}
</div>
You will have this following error:
Error: Template parse errors:
There is no directive with "exportAs" set to "elt.title" ("
<div *ngFor="#elt of eltList" >
<span [ERROR ->]#localVariable="elt.title"></span>
{{localVariable}}
</div>
"): AppComponent#2:10
Angular2 actually looks for a directive matching the provided name elt.title here)... See this plunkr to reproduce the error: https://plnkr.co/edit/qcMGr9FS7yQD8LbX18uY?p=preview
See this link: http://victorsavkin.com/post/119943127151/angular-2-template-syntax, section "Local variables" for more details.
In addition to the current element of the iteration, ngForm only provides a set of exported values that can be aliased to local variables: index, last, even and odd.
See this link: https://angular.io/docs/ts/latest/api/common/NgFor-directive.html
What you could do is to create a sub component to display elements in the loop. It will accept the current element as parameter and create your "local variable" as attribute of the component. You will be able then to use this attribute in the template of the component so it will be created once per element in the loop. Here is a sample:
#Component({
selector: 'elt',
template: `
<div>{{attr}}</div>
`
})
export class ElementComponent {
#Input() element;
constructor() {
// Your old "localVariable"
this.attr = createAttribute(element.title);
}
createAttribute(_title:string) {
// Do some processing
return somethingFromTitle;
}
}
and the way to use it:
<div *ngFor="#elt of eltList" >
<elt [element]="elt"></elt>
</div>
Edit
After your comment, I think that you try the approach described in this answer. Here are more details: create dynamic anchorName/Components with ComponentResolver and ngFor in Angular2.
Hope it helps you,
Thierry
You could stick it into the template interpolation since it handles expressions.
<div *ngFor="#elt of eltList" >
<span>{{setLocalVariable(#elt)}}</span>
</div>
setLocalVariable(_title : string){
let var = do some stuff to _title;
return var;
}