Polymer 2 - Data binding innerHTML - polymer

I have child-component inside parent-component. The child-component has a property item-checked with type boolean.
I need to inject the child-component to the parent-component using innerHTML, but that would break the binding.
I have tried using Templatize, but not sure what's wrong. It says: Cannot read property '__templatizeOwner' of null
<div id="page"></div>
<paper-toggle-button checked="{{powerChecked}}">
<font color="white">hide/show</font>
</paper-toggle-button>
The toggle execute this code
this.$.page.innerHTML = "
<child-component name='child-component' id='map' power-checked={{powerChecked}}>
</child-component>"

Related

Uncaught Invariant Violation: Objects are not valid as a React child (found: [object HTMLInputElement])

I am getting some form elements from an API, API response is given like this:
I have parsed that string with DOMParser as HTMLElement and I want to add that as React component, the form element is given below:
on getting this I am setting the form element in a state formEl, I added the state in my render function but it is giving the above error, my component is written like this:
{gateway.name === "KiplePay" && (
<div className="col-12 mb-4 mt-4 paymentGatewayBlock">
<button onClick={this.onClickKiplepay}>Pay with Kiplepay</button>
</div>
)}
{this.state.formEl}
The error says it is still an object, maybe I have to convert it to HTML element, but how do I do that? it is showing already an HTML element in console.

display variable html image

In Angular 2 code, I have defined the image as:
public rObj:any = {};
this.rObj.imgsrc ="http:/../.png";
Want to render this from my HTML:
<img src = {{rObj.imgsrc}}>
There is no display.Any help appreciated.Thanks!
Use one way binding on the src attribute. Any html attribute can be bound to.
... so for you this is what you are looking for.
<img [src]="rObj.imgsrc" />
Another example..
<a [href]="myHref"></a>
You are using the wrong data binding:
string binding: <elt attr="Hello World"/>
input (component → template): <elt [attr]="x"/>
event listener (template → component): <button (click)="someFunction"/>
two-way data binding: <elt [(attr)]="x"/> (not used a lot, use forms instead)
So you actually need here to write <img [src]="rObj.imgsrc"/>

how to bind component variable to form object instance property

I am not quite sure how to bind a variable from my component class to a property value in my form object. The form needs to display this value and add it to the ngModel so that it can become part of the object instance.
I am struggling with the syntax and keep getting the errorNo value accessor for form control with name: 'per_print'
Error: No value accessor for form control with name: I think I need to use the [(ngModel)]="myObject.property" syntax, but I am not getting this from an input into the form, but from a binded variable on the class.
<div class="form-group">
<label class="label-text" >Per Print</label>
<div class="input-group" style="width:150px;">
<h4 [(ngModel)]="job_entry.per_print" name="per_print"
value='pricePerPrint' class="form-control"
>
{{pricePerPrint | currency:'GBP':true:'1.2-2'}}
</h4>
</div>
</div>
job_entry is my object which properties I am setting through the form. pricePerPrint is a variable on the class. I want to set this variable to one of the form instance properties. How to do this? I thought I could do it through value, as in the value of the <h4> tag, but this error persists.
You could use [hidden] input field with the value you want, so that this value will be added to your form. This means though, that you need to use pricePerPrint as the ngModel. But ngModel for your job_entry is possibly not needed. You could build the form as such, so that the object you get from the form can be assigned directly to job_entry:
onSubmit(obj) {
this.job_entry = obj;
}
Also check the Demo for that.
So your code would look like this:
<form #myForm="ngForm" (ngSubmit)="onSubmit(myForm.value)">
<input [hidden]="isHidden" name="per_print"
[(ngModel)]="pricePerPrint" [value]="pricePerPrint"/>
<h4>Price: {{pricePerPrint}}</h4>
<button type="submit">Submit</button>
</form>
where isHidden is set to true.
Other option I see, if you want to use [(ngModel)]="job_entry.per_print, you need to assign whatever value you have in pricePerPrint to job_entry.per_print.

angular2 custom directives inputs syntax

I create a custom directive and set the selector value to be "[unless-directive]".
The directive get a Boolean and use it to change the view as so:
import {Directive, TemplateRef, ViewContainerRef} from 'angular2/core';
#Directive({
selector: '[unless-directive]',
inputs: ['givenBoolean : myDirectiveFunction']
})
export class UnlessDirective {
private _templateRef: TemplateRef;
private _viewContainerRef: ViewContainerRef;
constructor(_templateRef: TemplateRef, _viewContainerRef: ViewContainerRef) {
this._templateRef = _templateRef;
this._viewContainerRef = _viewContainerRef;
}
set myDirectiveFunction(condition: boolean) {
!condition ? this._viewContainerRef.createEmbeddedView(this._templateRef)
: this._viewContainerRef.clear();
}
}
In my template I tried to pass the condition like so:
<div name="customDirective">
<h2>Custom Directive</h2>
<div>
Enter true or false:
<br/>
<input type="text" #condition (keyup)="0"/>
<div *unless-directive [givenBoolean]="condition.value != 'false'">
Only shown if 'false' wad enterded!
</div>
</div>
</div>
When I running the code I get this error:
EXCEPTION: Template parse errors: Can't bind to 'givenBoolean' since
it isn't a known native property (" ... Only shown if 'false' wad enterded!"): StructualDirectivesComponent#47:39
I guess my syntax is wrong, but I can't find where or why?
I looked it up on Angular2 Docs, but the example use the same name for the input and the selector, the thing that I'm trying to avoid.
Can anyone know a better way or can find my syntax problem?
Thanks.
The * prefix syntax is only a syntatic sugar. It expands the directive declaration.
The * prefix syntax is a convenient way to skip the <template> wrapper tags and focus directly on the HTML element to repeat or include. Angular sees the * and expands the HTML into the <template> tags for us.
This is documented in * and <template> and Directive decorator/Lifecycle hooks.
So, in your case, the [givenBoolean] property is not expected to be in the directive. In other words, this:
<div *unless-directive [givenBoolean]="condition.value != 'false'">
Only shown if 'false' wad enterded!
</div>
Becomes, actually:
<template [unless-directive]="">
<div [givenBoolean]="condition.value != 'false'">
Only shown if 'false' wad enterded!
</div>
</template>
And since givenBoolean is not a property in the component (not the directive), the error appears.
So if you want custom behavior, I suggest you experiment using the expanded version and only after it works you go to the * syntax, it will be simpler to reason about.

Polymer 1.0 - Binding css classes

I'm trying to include classes based on parameters of a json, so if I have the property color, the $= makes the trick to pass it as a class attribute (based on the polymer documentation)
<div class$="{{color}}"></div>
The problem is when I'm trying to add that class along an existing set of classes, for instance:
<div class$="avatar {{color}}"></div>
In that case $= doesn't do the trick. Is any way to accomplish this or each time that I add a class conditionally I have to include the rest of the styles through css selectors instead classes? I know in this example maybe the color could just simple go in the style attribute, it is purely an example to illustrate the problem.
Please, note that this is an issue only in Polymer 1.0.
As of Polymer 1.0, string interpolation is not yet supported (it will be soon as mentioned in the roadmap). However, you can also do this with computed bindings. Example
<dom-module>
<template>
<div class$="{{classColor(color)}}"></div>
</template>
</dom-module>
<script>
Polymer({
...
classColor: function(color) {
return 'avatar '+color;
}
});
<script>
Edit:
As of Polymer 1.2, you can use compound binding. So
<div class$="avatar {{color}}"></div>
now works.
Update
As of Polymer 1.2.0, you can now use Compound Bindings to
combine string literals and bindings in a single property binding or text content binding
like so:
<img src$="https://www.example.com/profiles/{{userId}}.jpg">
<span>Name: {{lastname}}, {{firstname}}</span>
and your example
<div class$="avatar {{color}}"></div>
so this is no longer an issue.
The below answer is now only relevant to versions of polymer prior to 1.2
If you are doing this a lot, until this feature becomes available which is hopefully soon you could just define the function in one place as a property of Polymer.Base which has all of it's properties inherited by all polymer elements
//TODO remove this later then polymer has better template and binding features.
// make sure to find all instances of {{join( in polymer templates to fix them
Polymer.Base.join = function() { return [].join.call(arguments, '');}
and then call it like so:
<div class$="{{join('avatar', ' ', color)}}"></div>
then when it is introduced by polymer properly, just remove that one line, and replace
{{join('avatar', color)}}
with
avatar {{color}}
I use this a lot at the moment, not just for combining classes into one, but also things like path names, joining with a '/', and just general text content, so instead I use the first argument as the glue.
Polymer.Base.join = function() {
var glue = arguments[0];
var strings = [].slice.call(arguments, 1);
return [].join.call(strings, glue);
}
or if you can use es6 features like rest arguments
Polymer.base.join = (glue, ...strings) => strings.join(glue);
for doing stuff like
<div class$="{{join(' ', 'avatar', color)}}"></div>
<img src="{{join('/', path, to, image.jpg)}}">
<span>{{join(' ', 'hi', name)}}</span>
of just the basic
Polymer.Base.join = (...args) => args.join('');
<div class$="{{join('avatar', ' ', color)}}"></div>
<template if="[[icon_img_src]]" is="dom-if">
<img class$="{{echo_class(icon_class)}}" src="[[icon_img_src]]">
</template>
<span class$="{{echo_class(icon_class, 'center-center horizontal layout letter')}}" hidden="[[icon_img_src]]">[[icon_text]]</span>
<iron-icon icon="check"></iron-icon>
</div>
</template>
<script>
Polymer({
echo_class: function(class_A, class_Z) {
return class_A + (class_Z ? " " + class_Z : "");
},