Angular Dart: How can we iterate object into html? - dart

I have one proto object in angular dart I am taking values from proto object into dart object but I am unable to iterate it into html. How can I achieve this thing into dart like we do in angular?
Var obj=[{name:”test”}];
Html:
{{obj[0][‘name’]}}
I have tried to create object like:
List<Map<String,String>> details;
details= [{‘name’:’test’}];
Html:
{{details[0][‘name’]}}
But I am getting error ‘the getter is not defined for the class’.

Try the following code below:
Dart file:
List<Fields> fields = [
Fields("Jess", 10),
Fields("Sujuta", 11),
];
class Fields {
final String name;
final int age;
const Fields(this.objectName, this.age);
}
HTML file:
<div *ngFor="let field of fields">{{field.name}}</div>

Related

Can I create a const object from a json string?

I want to create a const object from a fixed JSON string.
This json string is comming from a --dart-define parameter.
I'm getting it using const _APP_CONF = String.fromEnvironment('APP_CONF', defaultValue: '{}');
I've tried the code below, but it is not working. the compiler is complaining about the second constructor:
class AuthnProvider {
final String id;
final String clientId;
final List<String> scopes;
const AuthnProvider(
{this.id,
this.clientId,
this.scopes});
const AuthnProvider.fromJson(final Map<String, dynamic> json)
: id = json['id'],
clientId = json['clientId'],
scopes = json['scopes'].cast<String>();
The json parameter is coming from json.decode() method.
I also tried to create const and final var from from the json map and use the first constructor, but compiler gives error too.
This is expected. const create a compile-time constant. Dart does not execute code during compilation and therefore cannot create a const from a Map. This is the reason const constructors can't have a body and why there is no other way to work around this limitation.
You don't mention the reason for doing this in your question, but if it's for performance, the difference will be negligible. If it's for immutability, all the fields we see are already final, so making the object const makes no difference.

Set paper-tooltip from dart

In html paper-tooltip works fine like
<div>
Text
<paper-tooltip>The tooltip</paper-tooltip>
</div>
But howto build apaper-tooltip from dart?
DivElement divText = new DivElement();
divText.text = 'Text from dart';
PaperTooltip pT = document.createElement('paper-tooltip');
//How to set the tooltip String "The tooltip" on pT?
divText.append(pT);
I have tried to set the underlying content of paper-tool, but don't succeed. Anyone with a tip on how this maybe could be done?
Not sure what is going on here. Seems like the creation from dart with document.createElement('paper-tooltip'); don't give a proper paper-tooltip element.
Found an ok workaround by wrapping the paper-tooltip with a custom element. The custom element can be then created with document.createElement('papertooltip-wrap');
Html
<dom-module id="papertooltip-wrap">
<template>
<paper-tooltip>[[tooltipText]]</paper-tooltip>
</template>
</dom-module>
Dart
#PolymerRegister('papertooltip-wrap')
class PapertooltipWrap extends PolymerElement {
#property
String tooltipText;
PapertooltipWrap.created() : super.created(){
}
void setAnchorElement(Element e, final String tipText){
set('tooltipText', tipText);
append(e);
}
}

Seeming to set a 1-directional databind even though it should be bidirectional

Been working with 2 files: my_ajax_fetcher.data/html with the data as follows:
my_ajax_fetcher.dart
#HtmlImport('my_ajax_fetcher.html')
library webserver_ajax.lib.iron_ajax;
import 'package:web_components/web_components.dart';
import 'package:polymer/polymer.dart';
import 'package:polymer_elements/iron_ajax.dart';
import 'package:polymer_elements/iron_request.dart';
///Uses [IronAjax]
#PolymerRegister('my-ajax-fetcher')
class IronAjaxSample extends PolymerElement {
#property
String f_name;
#property
String l_name;
#property
int identification;
//IronAjax ia = querySelector('myAjaxId');
IronAjaxSample.created() : super.created(){
print("created.");
//ia.generateRequest();
}
#reflectable
void handleResponse ( [CustomEventWrapper cew, IronRequest ir] ){
print("handle response fired");
var data = ir.response;
f_name = data["f_name"];
l_name = data["l_name"];
identification = data["id"];
print("$f_name $l_name: $identification");
}
}
my_ajax_fetcher.html
<dom-module id="my-ajax-fetcher">
<template>
<iron-ajax id="myAjaxId" auto
url="http://localhost:8675/test_server/v1/users/35"
handle-as="json"
on-response="handleResponse" ></iron-ajax>
<div>First Name: {{f_name}}</div>
<div>Last Name: {{l_name}}</div>
<div>Student ID: {{identification}}</div>
</template>
</dom-module>
And when the ajax call finishes it will call handleResponse which will set f_name, l_name, identification variables. The issue is that i see the variables are set in the last line of handleResponse.
It doesn't set the markup according to say: First Name: Frank at all, it is just empty. I have determined that for some reason, handleResponse is a different scope than the other functions. How do i fix this?
In Dart you always need to use set(...) or any other method provided by Polymer to update data.
set('f_name', data["f_name"]);
set('l_name', data["l_name"]);
set('identification', data["id"]);
In JavaScript this is not necessary for fields of a Polymer element, only for properties of complex types (custom classes, collections, ...)
See also
https://github.com/dart-lang/polymer-dart/wiki/properties#list-mutation-methods
https://github.com/dart-lang/polymer-dart/wiki/data-binding-syntax#path-change-notification
https://pub.dartlang.org/packages/polymer_autonotify
https://pub.dartlang.org/packages/autonotify_observe

Dart Polymer: How to set a non-string field in custom at creation

I am writing a polymer app. I extend a polymer element as follows:
#CustomTag("custom-element")
class CustomElement extends PolymerElement {
#published List<String> years;
CustomElement.created() : super.created();
}
the corresponding html:
<link rel="import" href="../../../../packages/polymer/polymer.html">
<polymer-element name="custom-element" attributes="years">
<template>
Years listed are
<template repeat="{{ year in years }}">
<p> {{ year }} </p>
</template>
</template>
<script type="application/dart" src="custom_element.dart"></script>
</polymer-element>
and in a dart script referenced in the entry html file, after I have fetched some data from server I dynamically create such elements:
initPolymer().run((){
querySelect("#custom-elements").children.add(
new Element.tag("custom-element")
..id = "my_custom_element"
);
});
Given code works fine if years in CustomElement is set to some value, now I want to set it in my main script. If the property years was of type String then I would simply altered the last piece to
initPolymer().run((){
querySelect("#custom-elements").children.add(
new Element.tag("custom-element")
..id = "my_custom_element"
..setAttribute("years", "2010")
);
});
But the problem is that I need to set a whole List, not a single value. I can't figure out a way to do so. How would I go about this? Solutions and suggestions are very welcome.
EDIT:
So my main script looks as follow
void main(){
// in reality this list is fetched from the server
List<String> customYears = ['2010', '2011'];
initPolymer().run((){
querySelect("#custom-elements").children.add(
new Element.tag("custom-element")
..id = "my_custom_element"
// HERE I would like to set a public field *years*
// of the CustomElement
// the following does not work
// 1.
// ..setAttribute('years', customYears)
// Exception: Uncaught Error: type 'List' is not a subtype of type 'String' of 'value'.
// 2.
// ..setAttribute('years', toObservale(customYears))
// Exception: Uncaught Error: type 'ObservableList' is not a subtype of type 'String' of 'value'.
// 3.
// ..years = customYears
// ..years = toObservable( custom Years )
// NoSuchMethodError: method not found: 'years='
);
});
}
So the question is, how do I assign a value to a non-string member field of an instance of CustomElement outside the class itself? A straightforward assignment inside the class causes no problems, but this isn't what I seek for. I hope I explained myself more clearly now.
Basically #Ozan answers your actual question but there is an additional issue.
The element is not yet fully initialized when the code assigns the value. This is the reason Dart fails and tells you that HtmlElement doesn't have a setter years. After adding Polymer.onReady.then() Polymer is fully initialized and the assignment works.
Hint: If you cast the created element to its concrete type you don't get a warning in DartEditor.
import 'package:polymer/polymer.dart';
import 'dart:html';
// added import to be able to use the type
import 'custom_element.dart';
void main() {
// in reality this list is fetched from the server
List<String> customYears = ['2010', '2011'];
// Polymer => 0.16.0
initPolymer().then((zone) => zone.run(() {
Polymer.onReady.then((_) { // added - wait for onReady
querySelector("#custom-elements").children.add(
(new Element.tag('custom-element') as CustomElement)
..id = "my_custom_element"
..years = toObservable(customYears));
});
}));
}
it is more convenient to add a constructor to the custom element like
import 'package:polymer/polymer.dart';
import 'dart:html';
#CustomTag('custom-element')
class CustomElement extends PolymerElement {
factory CustomElement() {
final x = new Element.tag('custom-element');
return x;
}
CustomElement.created() : super.created();
#published List<String> years;
}
then you can create the element like
querySelector("#custom-elements").children.add(
new AppElement()
..id = "my_custom_element"
..years = toObservable(customYears));
see also
Instantiating polymer element via dart code
how to implement a main function in polymer apps
Try to simply assign the value to the field:
import 'package:observe/observe.dart';
initPolymer().run((){
querySelect("#custom-elements").children.add(
new Element.tag("custom-element")
..id = "my_custom_element"
..years = toObservable(["2010"])
);
});
Usually custom elements are used in a main polymer element and attributes like years are bound to its scope:
<link rel="import" href="../../../../packages/polymer/polymer.html">
<polymer-element name="main-element">
<template>
<custom-element years="{{years}}"></custom-element>
</template>
<script type="application/dart" src="main_element.dart"></script>
</polymer-element>
#CustomTag("main-element")
class MainElement extends PolymerElement {
#published List<String> years = toObservable(["2010"]);
MainElement.created() : super.created();
}

Polymer custom element property not accessible in nested template

I have a custom element like below:
<polymer-element>
<template if="{{primaryLoaded}}">
<template repeat="{{pData in primaryData}}">
<p>{{pData.propertyOne}}</p>
<p>{{someClass.someOperation()}}</p>
<template if="{{secodaryLoaded}}">
<p>{{secondaryData.someProperty}}</p>
<p>{{someClass.someOperation()}}</p>
</template>
</template>
</template>
</polymer-element>
and a corresponding dart file:
class CustomElement extends PolymerElement with ObservableMixin
{
#observable bool primaryLoaded = false;
#observable bool secondaryLoaded = false;
#observable var primaryData;
#observable var secondaryData;
#observable var someClass;
void created()
{
primaryData = toObservable(new List<var>());
secondaryData = toObservable(new List<var>());
}
void inserted()
{
someClass = new SomeClass();
loadPrimaryData().then((pData) {
primaryData = pData;
primaryLoaded = true;
loadSecondaryData().then((sData) {
secondaryData = sData;
secondaryLoaded = true;
});
});
}
}
Everything works fine for the primaryData. Its properties get printed and the call to someOperation() on someClass prints its data correctly.
The problem is in the nested template. Nothing under the <template if="{{secondaryLoaded}}"> gets displayed. Even the call to someClass.someOperation() fails to display anything.
Is there a problem with scope here? It looks like the outer template can reference the properties defined in the dart file without problem but the nested template can't.
I read about setting variables as globals in the template by setting a custom binding delegate here. However, I can't set the bindingDelegate in my custom element as isTemplate returns false.
Is there any other way of setting a global variable in a custom template? Or am I going about this all wrong?
It's a bug. You can star this issue to be notified of changes:
https://code.google.com/p/dart/issues/detail?id=12742
The only thing you can do for now is to turn nested templates into other polymer elements or figure out a way so the template isn't nested.
In your case, instead of using if="primaryLoaded" you could just set primaryData = null and the template shoud not display anything until primaryData is set, assuming primaryData is #observable.

Resources