alasql select from object rather than array - alasql

For good reasons not worth explaining, I would like to use alasql to pull a numeric value from a nested json object. According to the docs it seems like this should work:
const data = {a:{b:42}};
const answer = alasql('select a->b from ?',[data])
But that gives me back this nonsense rather than the answer of 42 that I want:
[ { 'a->b': undefined } ]
I also tried this (where the input data is not an array):
const data = {a:{b:42}};
const response = alasql('select a->b from ?',data);
But that gives me this unhelpful error: Data source number 0 in undefined
This works and returns 42 a I would expect:
alasql('select value {a:{b:42}}->a->b')
And this also works:
const data = {a:{b:42}};
const response = alasql('select value '+JSON.stringify(data)+'->a->b')
But it seems crazy to shove the data in as a stringified object.
Is there a way to get alasql to just treat my object like an object and let me take it apart with -> operator?

Related

How do I convert an array in a map to array of strings

I'm trying to convert this map {[string1,string2]}
in to an array like this
[string1, string2]
in dart
A declaration of that kind in Dart is a Set(which is like a list but cannot have duplicates) of Lists, given that to get the first value you should just use
obj.first
(Sets are declared like maps but without any key)
This is a Set.
So you can do this for convert it to list:
Set<List<String>> map = {['string1','string2']};
List list = [];
map.forEach((k) {
k.forEach((item) => list.add(item));
});
as already mentioned in other answers this is a Set
you can easy convert it to List like this
var mySet = {['string1', 'string2']};
var list = mySet.expand((e) => e).toList();
print(list); // [string1, string2]
The 'map' you gave has one key (list of strings), which seems to be missing a value.
If your map looked something like this:
Map<List<String>, int> map = {[string1,string2]: 0};
Then you could get an Iterable of your keys (or values if you wish) with:
dynamic temp = map.keys //for the keys or
//or temp = map.values //for the values
You can further convert that Iterable into a List by calling the function toList() on it:
List<String> myList = temp.toList();
I hope this answered your question.
And if you are not sure what the type of your object is, use:
print(yourObject.runTimeType);

Returning Array of Objects shows only one object in next step

Ive been working on a code zap step to make a get call to an api endpoint, and then transform the response into key pair objects to pass to further steps in zapier.
var fileIds = [],
tempData = [],
newData = [],
obj = [];
fetch('zoho getClientById endpoint'+inputData.id)
.then(function(res) {
return res.json();
})
.then(function(json) {
tempData = json.response.result.Leads.row.FL;
for(var i = 0; i < tempData.length; i++ ){
tempVal = tempData[i].val;
newData = tempData[i].content;
let allData = {};
allData[tempVal] = newData;
obj.push(allData)
}
callback(null, obj);
}).catch(callback);
Above is more or less the code Im using. It works, except that when the array of objects comes out of the step, only the first object is available for steps after. Im not certain if this is because of the way Im handling it, or if it's something with how zapier works.
Edit: What's interesting is I can use the log statement to see results in the meta data, and it shows the full array of objects.
So, after a little extra reading, it seems that zapier will take each object in an array and try trigger another step with it. I updated my set up to just take the empty object I initially created and set a key with a value based off the value and content responses from my other response.

How does the Dart URI class QueryParameters handle Map values?

According to the documentation, it needs to follows the Form Post rules at: https://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4. When looking at that information it did not give me much to work with in terms of complex objects or maps.
Right now, If I have a list for example: Each item in the list needs to be stringified.
var params = {"list": [1,2,3]};
// needs to be stringed.
params["list"] = params["list"].map((item)=>item.toString()).toList();
Simple. Also all base items need to be a string as well
var params = {"number": 1, "boolean": true};
params = params.forEach((k,v)=> params[k].toString());
But how do we handle maps?
var params = {"map": {"a":1,"b":"foo","c":false,"d":[]}};
// ??
It seems that after testing in my app and in dart pad, you need to make sure everything is strings, so i am trying to come up with a way to effectively cover lists, maps, and maybe more complex objects for encoding.
var params = {};
params["list"] = [1,2,3];
params["number"] = 1;
params["boolean"] = true;
params["map"] = {"a":1,"b":"foo","c":false,"d":[]};
params.forEach((String key, dynamic value){
if(value is List){
params[key] = value.map((v)=>v.toString()).toList();
}else if(value is Map){
// ????
}else{
params[key] = value.toString();
}
//maybe have an additional one for custom classes, but if they are being passed around they should already have their own JSON Parsing implementations.
}
Ideally, the result of this would be passed into:
Uri myUri = new Uri(queryParameters: params);
and right now, while i solved the list issue, it doesn't like receiving maps. Part of me just wanted to stringify the map as a whole, but i wasn't not sure if there was a better way. I know that when someone accidentally stringified the array, it was not giving me: ?id=1&id=2 but instead ?id=%5B1%2C2%5D which was not correct.
I don't think there is any special support for maps. Query parameters itself is a map from string to string or string to list-of-strings.
Everything else need to be brought into this format first before you can pass it as query parameter.
A simple approach would be to JSON encode the map and pass the resulting string as a single query parameter.

Getting all l10n values stored in localized bundle

I'm building a FF extension, and I'm processing some xhtml for myself in order to supporn subforms loading, so I have to identify the elements with l10n attributes defined and add them the string value. Because the l10n can't be shared from main code to content scripts (because isn't a simple JSON object), I managed the situation by getting the loaded keys values and defining an "localized array bundle", like this:
lStrings = ["step_title", ........ ];
for (var i = 0; i < lStrings.length; i++) {
bundle[lStrings[i]] = this.locale(lStrings[i]);
}
The thing is, I have to write here every entry in the .properties files... SO, do you know how to access this key values? I already tryed with .toString .toLocalString and inspecting the object, but can't find the way the object to be capable of returning all the key collection.
Do you have a better idea for improvement?
var yourStringBundle = Services.strings.createBundle('chrome://blah#jetpack/content/bootstrap.properties?' + Math.random()); /* Randomize URI to work around bug 719376 */
var props = yourStringBundle.getSimpleEnumeration();
// MDN says getSimpleEnumeration returns nsIPropertyElement // https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIStringBundle#getSimpleEnumeration%28%29
while (props.hasMoreElements()) {
var prop = props.getNext();
// doing console.log(prop) says its an XPCWrappedObject but we see QueryInterface (QI), so let's try QI'ing to nsiPropertyElement
var propEl = prop.QueryInterface(Ci.nsIPropertyElement);
// doing console.log(propEl) shows the object has some fields that interest us
var key = propEl.key;
var str = propEl.value;
console.info(key, str); // there you go
}
See comments for learning. Nice quesiton. I learned more about QI from replying.

getPixel32 is inaccurate

function encodeBmp(s:String){
s = Base64.Encode(s);
var width:Number = Math.ceil(Math.sqrt(s.length/4));
var bmp:BitmapData = new BitmapData(width,width,true,0x00000000);
var pos:Number=0; //track position in string
for(var x:Number=0;x<width;x++){
for(var y:Number=0;y<width;y++){
var col="0x";
for(var i:Number=0;i<4;i++){
col+=getHex(s.charAt(pos));
pos++;
}
bmp.setPixel32(x,y,col);
trace(col + " > 0x" + bmp.getPixel32(x,y).toString(16));
}
}
return bmp.clone();
}
Basically, the trace statement returns this:
0x56326868 > 0x56326868
0x64434270 > 0x64424270
0x63794230 > 0x63794331
...
Why is the result of getPixel32 different from that of the set value, and how can I resolve this?
EDIT: getPixel is accurate, but doesn't have the extra bit that get/setPixel32 does... I would prefer to have more data per pixel.
You're Base64 encoding a String to store it in a BitmapData. I hope you didn't know that, or are ashamed.
Anyway, here is what I see happening:
First, if you type col as a String, you'll get a compile error on setPixel32, because it's expecting a uint.
Now, we can ignore all the looping and hex strings to get some simple code to reproduce the problem.
var bitmapData:BitmapData = new BitmapData(1, 1);
bitmapData.setPixel32(0, 0, 1682129520);
trace(bitmapData.getPixel32(0, 0));
By using an int literal, we can see that it's not a problem with type coercion, but something inside of BitmapData. This makes sense, since BitmapData is intended to store graphics data, so storing the graphics in a way that is graphically similar but not exact is fine.
You're probably seeing the side-effects of pre-multiplied alpha in Flash. This would also explain why you don't see any problems with getPixel and setPixel.
You can read more about it here: http://www.quasimondo.com/archives/000665.php
So how do you fix the problem? Use the correct data type. A ByteArray is designed to store binary data.

Resources