Polymer: Passing array to property via markup - javascript

I have created an element which has an array property 'icon-buttons'. I can pass the array using javascript but when I pass it in the markup itself, it does not work.
Property:
iconButtons: {
type: Array,//tried Object as well
value: function() { return []; }
}
Usage:
<my-card heading="Demo 2" icon-buttons='[
{"name" : "edit", "icon" : "icons:create", "click" : "toggleMode();", "disabled" : false},
{"name" : "close", "icon" : "icons:clear", "click" : "alert(''close'');", "disabled" : false},
{"name" : "maximize", "icon" : "icons:fullscreen", "click" : "alert(''maximize'');", "disabled" : false},
{"name" : "more", "icon" : "icons:more-vert", "click" : "alert(''more'');", "disabled" : true}
]'>
<div class="card-content">
<list mode="edit"></list>
</div>
<div class="card-actions">
<paper-button>Hello</paper-button>
<paper-button>Bye</paper-button>
</div>
</my-card>
I have passed a JSON object similarly for another element. But this one with Array does not work.
What is wrong in this?

a1626 is right, use \" instead of '' in your alerts
... "click": "alert(\"close\");", ...

Related

"Evaluate" Function that is stored in MongoDB Server

My collection looks like this:
> db.projects_columns.find()
{ "_id" : "5b28866a13311e44a82e4b8d", "checkbox" : true }
{ "_id" : "5b28866a13311e44a82e4b8e", "field" : "_id", "title" : "ID", "sortable" : true }
{ "_id" : "5b28866a13311e44a82e4b8f", "field" : "Project", "title" : "Project", "editable" : { "title" : "Project", "placeholder" : "Project" } }
{ "_id" : "5b28866a13311e44a82e4b90", "field" : "Owner", "title" : "Owner", "editable" : { "title" : "Owner", "placeholder" : "Owner" } }
{ "_id" : "5b28866a13311e44a82e4b91", "field" : "Name #1", "title" : "Name #1", "editable" : { "title" : "Name #1", "placeholder" : "Name #1" } }
{ "_id" : "5b28866a13311e44a82e4b92", "field" : "Name #2", "title" : "Name #2", "editable" : { "title" : "Name #2", "placeholder" : "Name #2" } }
{ "_id" : "5b28866a13311e44a82e4b93", "field" : "Status", "title" : "Status", "editable" : { "title" : "Status", "type" : "select", "source" : [ { "value" : "", "text" : "Not Selected" }, { "value" : "Not Started", "text" : "Not Started" }, { "value" : "WIP", "text" : "WIP" }, { "value" : "Completed", "text" : "Completed" } ], "display" : "function (value, sourceData) { var colors = { 0: 'Gray', 1: '#E67C73', 2: '#F6B86B', 3: '#57BB8A' }; var status_ele = $.grep(sourceData, function(ele){ return ele.value == value; }); $(this).text(status_ele[0].text).css('color', colors[value]); }", "showbuttons" : false } }
You can see that in the very last document that I have stored a function as text.Now the idea is that I will request this data and will be in an Javascript Array format.
But I want to be able to have my function without the quotes! You can see that simply evaluating it will not work because I need to have it still needs to be inside of the object ready to be executed when the array is used.
How can I achieve this?
Thanks for any help!
There are two possible solutions, but neither particularly safe and you should strongly consider why you need to store functions as strings in the first place. That being said, you could do two things.
The simplest is to use eval. To do so, you would have to first parse the object like normal, and then set the property that you want to the result of eval-ing the function string, like so:
// Pass in whatever JSON you want to parse
var myObject = JSON.parse(myJSONString);
// Converts the string to a function
myObject.display = eval("(" + myObject.display + ")");
// Call the function with whatever parameters you want
myObject.display(param1, param2);
The additional parentheses are to make sure that evaluation works correctly. Note, that this is not considered safe by Mozilla and there is an explicit recommendation not to use eval.
The second option is to use the Function constructor. To do so, you would need to restructure your data so that you store the parameters separately, so you could do something like this:
var myObject = JSON.parse(myJSONString);
// displayParam1 and displayParam2 are the stored names of your parameters for the function
myObject.display = Function(myObject.displayParam1, myObject.displayParam2, myObject.display)
This method definitely takes more modification, so if you want to use your existing structure, I recommend eval. However, again, make sure that this is absolutely necessary because both are considered unsafe since outside actors could basically inject code into your server.

Add new element to array with setState

How to add new element to array with setState
I have this data
this.state = {
items : [
{ "id" : "324", "parent" : "qqqq", "text" : "Simple root node" },
{ "id" : "24", "parent" : "dwdw", "text" : "Root node" },
{ "id" : "55", "parent" : "ajson2", "text" : "Ch" },
{ "id" : "9866", "parent" : "ajson2", "text" : "oiiojio" },
]
}
I'm mapping the data
{this.state.items.sort((a,b) => a.newID < b.newID).map((item)=>
<ul>
<li key={item.id}><span>ID: </span>{item.id} <span>parent: </span>{item.parent} <span>text: </span>{item.text}</li>
</ul>
)}
and then I'm sorting the data by newID That I need to create it with setState
this.setState(prevState=>({newData: [...prevState.items, this.props.account.info]}));
How can I create new element with this.props.account.info add somthing like i++ I don't know actually
this.props.account.info It's adding data like
{ "id" : "324", "parent" : "qqqq", "text" : "Simple root node" }
So I need to add an element inside this will be like
{ "newID": "1", "id" : "324", "parent" : "qqqq", "text" : "Simple root node" }
So if you want to add "newID" field in the object, there is a way to do this using object spread operator.
{...this.props.account.info, "newID":"1"}
This will give you a new object with the "newID" field added with "1" as its value associated with it.
This is a shorthand for this:
Object.assign({}, this.props.account.info, {"newID": "1"});

get data through JSON

I have some JSON below, What I would like to do is iterate through the JSON file and pull out the 'title' element and make a list. Could anybody help?
{ "slides" : {
"sl_0_0" : {
"title" : "Slide 0-0",
"copy" : "Copy for slide 0-0",
"link" : "sl_0_0.html"
},
"sl_1_0" : {
"title" : "Slide 1-0",
"copy" : "Copy for slide 1-0",
"link" : "sl_1_0.html"
},
"sl_1_1" : {
"title" : "Slide 1-1",
"copy" : "Copy for slide 1-1",
"link" : "sl_1_1.html"
},
"sl_2_0" : {
"title" : "Slide 2_0",
"copy" : "Copy for slide 2_0",
"link" : "sl_2_0.html"
},
"sl_2_1" : {
"title" : "Slide 2_1",
"copy" : "Copy for slide 2_1",
"link" : "sl_2_1.html"
},
"sl_2_2" : {
"title" : "Slide 2_2",
"copy" : "Copy for slide 2_2",
"link" : "sl_2_2.html"
}
}
}
You treat a JSON object just as you would any other javascript object. So, you can interate through it using a for loops like this:
var jsonObj = { /* your JSON object here */ };
for ( var id in jsonObj.slides ) {
var slide = jsonObj.slides[id];
var title = slide.title; //etc.
/* Now you can build your list */
}

java.lang.ClassCastException calling RedQueryBuilderFactory.create with args

This line in my JS file:
RedQueryBuilderFactory.create(config,
'SELECT "x0"."title", "x0"."priority" FROM "ticket" "x0" WHERE ("x0"."status" = (?))',
[]
);
works fine witih an empty array as the 3rd parameter. This parameter is supposed to be an array of strings according to the documentation and any sample code I can find. When I pass a string in the array it fails:
RedQueryBuilderFactory.create(config,
'SELECT "x0"."title", "x0"."priority" FROM "ticket" "x0" WHERE ("x0"."status" = (?))',
['in_process']
);
I get java.lang.ClassCastException in the Safari console. Here's the related part of the config if it's relevant:
var config = {
meta : {
tables : [ {
"name" : "ticket",
"label" : "Ticket",
"columns" : [ {
"name" : "title",
"label" : "Title",
"type" : "STRING",
"size" : 255
}, {
"name" : "priority",
"label" : "Priority",
"type" : "REF"
} ],
fks : []
} ],
types : [ {
"name" : "REF",
"editor" : "SELECT",
"operators" : [ {
"name" : "IN",
"label" : "any of",
"cardinality" : "MULTI"
}]
} ]
}
};
Looks like this is a bug in passing in parameter values. Internally it is expecting a collection but this is not happening.
Best if you raise a https://github.com/salk31/RedQueryBuilder bug report here?
NB Should be "IN" not "="

Knockout mapping does represent wished for html

I have a problem with knockout mapping. I'm using knockout mapping plugin to represent a form that is serialized in JSON. It was working before using the knockout mapping but I need to use knockout mapping since I want my properties to be observable.
You can see the working html here : http://jsfiddle.net/etiennenoel/wG9SZ
Here's my not working javascript code:
var formData =
{"data":
[
{
"groupName" : "Properties",
"content" :
[
{
"title" : "Calculation Method",
"formType" : "select",
"value" :
[
{
"title" : "Voltage Drop - Unbalanced",
"selected" : true
},
{
"title" : "Voltage Drop - Balanced"
}
]
},
{
"title" : "Tolerance (% V)",
"formType" : "textBox",
"value" : 0.01
},
{
"title" : "Calculation Options",
"formType" : "radio",
"value" :
[
{
"title" : "Flat Start (at Nominal Conditions",
"checked" : false
} ,
{
"title" : "Assume Line Transposition",
"checked" : true
}
]
},
{
"title" : "Adjust Conductor Resistance at",
"formType" : "textBox",
"disabled" : true,
"value" : 77,
"appendLabel" : true,
"appendLabelText" : "°F"
}
]
},
{
"groupName" : "Properties",
"content" :
[
{
"title" : "Calculation Method",
"formType" : "select",
"value" :
[
{
"title" : "Voltage Drop - Unbalanced",
"selected" : true
},
{
"title" : "Voltage Drop - Balanced"
}
]
},
{
"title" : "Tolerance (% V)",
"formType" : "textBox",
"value" : 0.01
},
{
"title" : "Calculation Options",
"formType" : "radio",
"value" :
[
{
"title" : "Flat Start (at Nominal Conditions",
"checked" : false
} ,
{
"title" : "Assume Line Transposition",
"checked" : true
}
]
},
{
"title" : "Adjust Conductor Resistance at",
"formType" : "textBox",
"disabled" : true,
"value" : 77,
"appendLabel" : true,
"appendLabelText" : "°F"
}
]
}
]
};
ko.mapping.fromJS(formData);
Here's the jsfiddle of the same code: http://jsfiddle.net/etiennenoel/wG9SZ/3/
What is the problem between when I use mapping and when I don't use it ?
In your second case you forgot to ApplyBindings.
ko.applyBindings(formData);
I don't know if this is the case with your scenario, but it's worth a post.
I had issues with the mapping plugin, when I had a more complex viewmodel with nested properties or lists. It turned out that after mapping to an already constructed viewmodel, the sub-objects were no more observables. With this issue, for me this code worked, what I've found somewhere (unfortunately I already really don't know where). I called this function for my viewmodel after mapping to that.
function makeAllObservables(observable) {
// Loop through its children
for (var child in observable()) {
// If this child is not an observable and is an object
if ((!ko.isObservable(observable()[child])) && (typeof observable()[child] === "object")) {
// Make it an observable
observable()[child] = ko.observable(observable()[child]);
// Make all of its children observables
makeAllObservables(observable()[child]);
}
}
};
Usage (when updating the model from server response, the first line should not be there):
var model = ko.observable({});
ko.mapping.fromJS(myJSObject, {}, model);
makeAllObservables(model);
ko.applyBindings(model);
I ment mapping to an already constructed viewmodel for example, when you want to update your viewmodel with new JSON data from server. In that case I lost nested bindings without the code above.
UPDATE: I've found the source where I borrowed the technique from, here. Note that I slightly modified that code in that post, because somehow that was not working for me.
You need to bind the mapped viewmodel to the view:
ko.applyBindings(ko.mapping.fromJS(formData));
and since everything is now an observable the logic in the view needs to be changed to use the method syntax:
<!-- ko if: $data.formType() === "select" -->
To get the options to display, you need to tell knockout what the property name is on the object:
<select data-bind="options: $data.value, optionsText: 'title'"></select>

Categories

Resources