I was building my project for Windows and everything was working fine. Now I started building it in HTML5 and I'm getting an error with map iterators:
for (entryMap in mapStruct.map)
{
var array:Array<Dynamic> = entryMap;
var keyObj = getJSONField(array[0], mapStruct.keyType);
var valueObj = getJSONField(array[1], mapStruct.valueType);
map.set(keyObj, valueObj);
}
And I get this error:
Exception name: TypeError: mapStruct.map.iterator is not a function
My project was working fine for Windows, but I don't know what to do, I need to use map like this.
I was trying to guess what is mapStruct without any success.
It looks like your aren't looping on a map in the right way...
Let's see some examples:
var map = ["hello" => 1, "world" => 4];
for (value in map)
{
trace('value: $value');
}
returns:
value: 1
value: 4
Here you have the link to try it online.
On the other hand, if you want to get either key and value, you should iterate it this way:
var map = ["hello" => 1, "world" => 4];
for (key in map.keys())
{
trace('key: $key value: ${map[key]}');
}
* Note the keys method call
And it returns:
key: hello value: 1
key: world value: 4
Here's the 'Try Haxe' link for it
if I knew which type mapStruct is, I'd probably help you more
Related
I am trying to write some tests using Mocha and Chai on an array of objects. I want to go through this array and return any objects that contain the error key. I figured this sort of thing would be easy, but I am having a difficult time of it.
[
{ fileName: 'font1.ttc', error: 'font_type_not_supported' },
{ fileName: 'font2.ttf', error: 'parse_failed' },
{ fileName: 'font3.tff' }
]
I've tried things like.
expect(testResult).to.have.nested.property('error');
I'm probably missing something simple, does anyone have any suggestions?
I think you can use node function filter to do your work.
Something like this works:
var array = [
{ fileName: 'font1.ttc', error: 'font_type_not_supported' },
{ fileName: 'font2.ttf', error: 'parse_failed' },
{ fileName: 'font3.tff' }
]
var filter = array.filter(item => item.error != undefined)
With this way you get the elements where exists the attribute.
But if you want to compare how many elements has the property, you can use length attribute.
var count = array.filter(item => item.error != undefined).length
expect(count).gt(0)
If count variable is greater than 0, implies that at least one object has the attribute.
So lets say I had a chained sequence like the following:
let amount = _
.chain(selectedItemsArray)
.map(item => _.find(availableItems, {id: item.id})
//how can I determine that ALL items were found right here?
.filter('price_money')
...
Note the comment in the code above. It could be possible that the selectedItemsArray is out of date, so some selected items might not be in availableItems. So, my initial thought was to use a .tap or .thru (probably tap) to do something like _.every(selectedItems, _.isObject) or something similar to catch the error state where not all items are found and throw an error if not all items were found. This feels odd though...any better ways of handling this type of error checking mid sequence?
Something like this does work (at least I can throw an error), but seems like I'm using tap for something it's not intended for:
.tap(items => {
if (!_.every(items, _.isObject)) throw new Error('Some selected items are no longer available');
})
You can use another _.filter to check if the element is not an object, and also handle the offending value. You can use || to execute fallback code. See this question.
If you want your code to crash and burn on the first failure, use a function that throws an error instead of using console.error.
var available = [
{ id: 1, amount: 2.00 },
{ id: 2, amount: 4.00 }
];
var selected = [1, 2, 3];
var amount = _(selected)
.map(item => _.find(available, {id:item}) || item)
.filter(item => _.isObject(item) || console.error("Item not available:", item))
.sumBy('amount');
console.log("Amount:", amount.toFixed(2));
<script src="https://cdn.jsdelivr.net/lodash/4.15.0/lodash.min.js"></script>
Is there an actionscript library providing a queuing system?
This system would have to allow me to pass the object, the function I want to invoke on it and the arguments, something like:
Queue.push(Object, function_to_invoke, array_of_arguments)
Alternatively, is it possible to (de-)serialize a function call? How would I evaluate the 'function_to_invoke' with the given arguments?
Thanks in advance for your help.
There's no specific queue or stack type data structure available in ActionScript 3.0 but you may be able to find a library (CasaLib perhaps) that provides something along those lines.
The following snippet should work for you but you should be aware that since it references the function name by string, you won't get any helpful compiler errors if the reference is incorrect.
The example makes use of the rest parameter which allows you to specify an array of arbitrary length as the arguments for your method.
function test(... args):void
{
trace(args);
}
var queue:Array = [];
queue.push({target: this, func: "test", args: [1, 2, "hello world"] });
queue.push({target: this, func: "test", args: ["apple", "pear", "hello world"] });
for (var i:int = 0; i < queue.length; i ++)
{
var queued:Object = queue[i];
queued.target[queued.func].apply(null, queued.args);
}
Sure, that works similar to JavaScript
const name:String = 'addChild'
, container:Sprite = new Sprite()
, method:Function = container.hasOwnProperty(name) ? container[name] : null
, child:Sprite = new Sprite();
if (method)
method.apply(this, [child]);
So a query method could look like:
function queryFor(name:String, scope:*, args:Array = null):void
{
const method:Function = scope && name && scope.hasOwnProperty(name) ? scope[name] : null
if (method)
method.apply(this, args);
}
So I want to allow the user to conditionally turn columns on/off in a Cardboard app I built. I have two problems.
I tried using the 'columns' attribute in the config but I can't seem to find a default value for it that would allow ALL columns to display(All check boxes checked) based on the attribute, ie. the default behavior if I don't include 'columns' in the config object at all (tried null, [] but that displays NO columns).
So that gets to my second problem, if there is no default value is there a simple way to only change that value in the config object or do I have to encapsulate the entire variable in 'if-else' statements?
Finally if I have to manually build the string I need to parse the values of an existing custom attribute (a drop list) we have on the portfolio object. I can't seem to get the rally.forEach loop syntax right. Does someone have a simple example?
Thanks
Dax - Autodesk
I found a example in the online SDK from Rally that I could modify to answer the second part (This assumes a custom attribute on Portfolio item called "ADSK Kanban State" and will output values to console) :
var showAttributeValues = function(results) {
for (var property in results) {
for (var i=0 ; i < results[property].length ; i++) {
console.log("Attribute Value : " + results[property][i]);
}
}
};
var queryConfig = [];
queryConfig[0] = {
type: 'Portfolio Item',
key : 'eKanbanState',
attribute: 'ADSK Kanban State'
};
rallyDataSource.findAll(queryConfig, showAttributeValues);
rally.forEach loops over each key in the first argument and will execute the function passed as the second argument each time.
It will work with either objects or arrays.
For an array:
var array = [1];
rally.forEach(array, function(value, i) {
//value = 1
//i = 0
});
For an object:
var obj = {
foo: 'bar'
};
rally.forEach(obj, function(value, key) {
//value = 'bar'
//key = 'foo'
});
I think that the code to dynamically build a config using the "results" collection created by your query above and passed to your sample showAttributeValues callback, is going to look a lot like the example of dynamically building a set of Table columns as shown in:
Rally App SDK: Is there a way to have variable columns for table?
I'm envisioning something like the following:
// Dynamically build column config array for cardboard config
var columnsArray = new Array();
for (var property in results) {
for (var i=0 ; i < results[property].length ; i++) {
columnsArray.push("'" + results[property][i] + "'");
}
}
var cardboardConfig = {
{
attribute: 'eKanbanState',
columns: columnsArray,
// .. rest of config here
}
// .. (re)-construct cardboard...
Sounds like you're building a neat board. You'll have to provide the board with the list of columns to show each time (destroying the old board and creating a new one).
Example config:
{
attribute: 'ScheduleState'
columns: [
'In-Progress',
'Completed'
]
}
I have a dijit.form.NumberTextBox input field that starts out with these parms:
new dijit.form.NumberTextBox({
id: din1,
style: "width:60px",
constraints: {
places: 0,
pattern: '######'
}
},
din1);
Everything works great..My question is I would like to change 'places' and 'pattern' parms on the fly. So I wrote this to change 'places' and 'patterns' parms:
var myFldObj = dijit.byId(din1);
if (myFldObj) {
var myConstObj = myFldObj.attr('constraints');
if (myConstObj) {
myConstObj.places = 2;
myConstObj.pattern = '#####.0';
}
}
So, after I show the form again, I'd expect the entry field to allow 2 decimal places but the form still acts like places=0 and pattern='######'. When I check the values of 'places' and 'pattern' I get what I'd expect (2 and #####.0). My question:
Can you change these values on the fly??
OR
Do you have to destroy the original dijit object and recreate with new parms??
Thx!!
So, here is what worked for me:
First, I think this is a bug because an input field that starts out like
new dijit.form.NumberTextBox({
id: "fieldID",
style: "width:60px",
constraints: {
places: 0
}
},
"fieldID");
that is then changed on the fly with code like:
NOTE: ntbArry - Array of dijit.form.NumberTextBox objs tied to a html
input tag id.
for (var x=0;x < ntbArry.length;x++) {
var handle = ntbArry[x];
if (handle) {
handle.attr('constraints').places = 2;
handle.attr('constraints').pattern = '#####.0#';
}
}
Does not exhibit the same behavior as a field created this way (no constraints mods on the fly):
new dijit.form.NumberTextBox({
id: "fieldID",
style: "width: 60px",
constraints: {
places: 2,
pattern: '#####.0#'
}
},
"fieldID");
It's close in behavior but every time you type a decimal point, the error message pops up stating invalid entry. This message doesn't pop up when typing the decimal point on a field that was originally created with the constraints places=2 and pattern '#####.0#'.
So, to get original behavior I wanted:
fieldIDEvents is an array of dojo events tied to NumberTextBox fields.
Before continuing disconnect dojo events
for (var x=0;x < fieldIDEvents.length;x++) {
var handle = fieldIDEvents[x];
if (handle) {
dojo.disconnect(handle);
}
}
then destroy the NumberTextBox dojo objects
for (var x=0;x < ntbArry.length;x++) {
var handle = ntbArry[x];
if (handle) {
handle.destroy();
ntbArry[x] = null;
}
}
Next, place the input tag back into the html because it gets destroyed:
NOTE: tdtag and an id on a html td tag which should contain the input tag.
var fld1 = this.document.getElementById("tdtag");
if (fld1) {
//alert("\""+fld1.innerHTML+"\"");
fld1.innerHTML = "<input id=\"fieldID\">";
}
Now, create the NumberTextBox object again:
ntbArry[0] = new dijit.form.NumberTextBox({
id: "fieldID",
style: "width: 60px",
constraints: {
places: 2,
pattern: '#####.0#'
}
},
"fieldID");
It's a few extra steps but, at least I know this is what works for me..If I'm missing something basic, let me know, it's easy to miss the small details with this stuff.
I use Dojo 1.3 and I can see that dijit.form.NumberTextBox has no pattern and places properties, but has editOptions property. So I would try to change the constraints like this:
myConstObj.editOption.places = 2;