unpacking GVariant in javascript - javascript

I have an array stored as a GVariant of type a(ss) in GSettings, that I want to use in a Cinnamon Applet. I can retrieve the value successfully using the following code:
let schema = schema_source.lookup(SCHEMA_NAME, false);
let settings = new Gio.Settings({ settings_schema: schema });
let my_value = settings.get_value('myvalue');
but I can't unpack it. As far as I can see, I will probably need to unpack it using a GVariantIter structure, but the documentation is limited, and I can't find the correct interface in the gjs API (if, indeed, it exists). Does anyone know how to do it?
Thanks!
edit:
my schema looks like this:
<key type="a(ss)" name="myvalue">
<default>[]</default>
<summary>an array of (string, string) tuples</summary>
<description></description>
</key>
For the time being I'm using an external JSON file to store settings, but it's not a 100% satisfactory solution. I suppose I could maintain two as-type variables, and keep them aligned, but there must be a way to do this properly, right?

A bit late, but my_value.unpack() works absolutely fine.
my_value.deep_unpack() will recursively unpack the arrays and their elements.

From your type of setting I guess you want to store/retrieve an array of strings? In this case, there is an easier method using Gio.Settings.get_strv(String key):
// Read the array (will create a real JS array):
let string_array = settings.get_strv("myvalue");
// Now do something with it...
// Store it:
settings.set_strv("myvalue", string_array);
Gio.Settings.sync(); // Important!
In your schema, you would then include an entry like this:
<key name="myvalue" type="as">
<default>[]</default>
<summary>Some array.</summary>
<description>An Array of strings.</description>
</key>
I use the same technique in my extension: Read/Write | Schema

Related

Reliably identify File Objects in JavaScript, like Hash or so

For uploading files in the Webbrowser, I implemented a file queue.
This is simply an Array that holds the file objects.
var filecache = new Array();
$(".fileinput").on("change", function (e) {
$.each(e.target.files, function (k, file) {
filecache.push(file);
});
});
Using this array, I need to have a function to remove specific files from that Array.
A File Object in JavaScript only contains a few properties: https://developer.mozilla.org/en-US/docs/Web/API/File
So when I want to remove a specific file from that FileObject-Aray, these are the properties I could use. But reliably is none of them. Two or more files in that Array can have the same name, so the name property will not be my choice.
I wonder if I could somehow create a Hash, a unique Key or something alike, out of the properties I have, to identify a specific file.
Is there a way to solve this problem? I know, Hashes are painful in JavaScript, but maybe someone knows another practical way.
You can add id property to file object and then put it to array.
id generation might be as trivial as function with state which returns incremented value or you can go even further and compute MD5 or CRC from the Blob.

JSON in localforage, efficient way to update property values (Binarysearch, etc.)?

I would like to come straight to the point and show you my sample data, which is around the average of 180.000 lines from a .csv file, so a lot of lines. I am reading in the .csv with papaparse. Then I am saving the data as array of objects, which looks like this:
I just used this picture as you can also see all the properties my objects have or should have. The data is from Media Transperency Data, which is open source and shows the payments between institiutions.
The array of objects is saved by using the localforage technology, which is basically an IndexedDB or WebSQL with localstorage like API. So I save the data never on a sever! Only in the client!
The Question:
So my question is now, the user can add the sourceHash and/or targetHash attributes in a client interface. So for example assume the user loaded the "Energie Steiermark Kunden GmbH" object and now adds the sourceHash -- "company" to it. So basically a tag. This is already reflected in the client and shown, however I need to get this also in the localforage and therefore rewrite the initial array of objects. So I would need to search for every object in my huge 180.000 lines array that has the name "Energie Steiermark Kunden GmbH", as there can be multiple and set the property sourceHash to "company". Then save it again in the localforage.
The first question would be how to do this most efficient? I can get the data out of localforage by using the following method and set it respectively.
Get:
localforage.getItem('data').then((value) => {
...
});
Set:
localforage.setItem('data', dataObject);
However, the question is how do I do this most efficiently? I mean if the sourceNode only starts with "E" for example we don't need to search all sourceNode's. The same goes of course for the targetNode.
Thank you in advance!
UPDATE:
Thanks for the answeres already! And how would you do it the most efficient way in Javascript? I mean is it possible to do it in few lines. If we assume I have for example the current sourceHash "company" and want to assign it to every node starting with "Energie Steiermark Kunden GmbH" that appear across all timeNode's. It could be 20151, 20152, 20153, 20154 and so on...
Localforage is only a localStorage/sessionStorage-like wrapper over the actual storage engine, and so it only offers you the key-value capabilities of localStorage. In short, there's no more efficient way to do this for arbitrary queries.
This sounds more like a case for IndexedDB, as you can define search indexes over the data, for instance for sourceNodes, and do more efficient queries that way.

JSON parsing a Titanium.App.Properties string

In an app, made with TideSDK; i assign a global variable (shocking I know) to a the JSON parse of a string stored in Titanium.App.Properties:
var workbookArray = JSON.parse(Titanium.App.Properties.getString('workbookArray'));
workbookArray is an array of objects.
And then on the unloading of a page, I assign Titanium.App.Properties string the value of workbookArray, which may have been changed by whoever has used the app:
Titanium.App.Properties.setString('workbookArray', JSON.stringify(workbookArray));
Each time I open the app, however, I'm told that JSON was unable to parse the first code snippet (initializing workbookArray).
Aside from this issue, I don't expect to use the app Properties API for my storage needs in the longterm, I wish i could use indexedDB with titanium. SQL is an option, but is a little messy when it comes to objects. Any other suggestions for a database solution?
Try getList and setList
http://docs.appcelerator.com/titanium/latest/#!/api/Titanium.App.Properties
What is stored in the list?

validating JSON file in JavaScript

My Google Chrome extension uses JSON.parse(oldJSONstring) to create an object with configuration information. The "oldJSONstring" was saved from previous sessions on Chrome's localStorage.
As I sometimes add new features, after I create the new object, I manually validate that all configuration entries exist, if not, I'll set them with default values. This is done, in case it's he firs time a user loads the extension after it updated.
I was trying to think of a more automatic way of doing this, like using a JSON Schmea, but I really don't know where to start, and my first round of google searches didn't produce anything I could use.
Another approach I thought was to iterate on all my Default settings -also stored on a JSON object- and then confirming they exist on the new object... but I just realized I don't know how to iterate a JSON object for all its attributes :)
The end goal of this is that I'd like to forget about validating for new attributes, every time I create a new feature and I publish a new version... does it make any sense? does it make me lazy? :D
Thanks!
Keep the default object handy and use jQuery $.extend to merge the 2 objects.
var defaults={ color:'blue', size:'Large'}
var chromeObj= /* code to grab from storage*/
/* update chromeObj with all key/value pairs in defaults */
/* regardless if they already exist or not*/
$.extend( chromeObj, defaults}
/* code to put chromeObj back to storage*/
Refrence: http://api.jquery.com/jQuery.extend/
There is no such thing as a "JSON object,"* but it's quite easy to loop over a Javascript object's properties: How do I loop through or enumerate a JavaScript object?
* JSON is just a string format, and it's a subset of Javascript object notation

Capturing form data: variables or array?

I have a form with about 20 input fields. I capture values of these fields, then do some calculations and output several values.
Is there a preferred/recommended way of capturing form data? Currently I store every form field into a separate variable. I was wondering if storing it to an array would be a better and more effective approach.
I'm quite new to Javascript and programming in general, trying to learn the best practices.
My best practice on this depends on what I have to do with the data. If I do not need to loop through it, or send it to another page/service, then there's nothing wrong with individual scoped-variables.
If I need to loop at all, I commonly use an array or object to loop through.
If I have to pass it to another page/service, I make one object variable to encapsulate the rest of them, so I can "stringify" it to JSON and parse back to an object on the other end.
Just my opinion,
Pete
You might consider the third approach - just use the data from the form without storing it anywhere.
First check the correctness, once it is considered correct just use what you have.
You should always assign the attribute "name=..." to an input element, so you can use something like:
var form = document.forms['form'];
var email = form['email'];
email = do something
if you use javascript... if you use jquery it's simple $('input[name="email"]') = do something
I prefer this way because you can call variables by name, not by number, for example "form[0] that corresponds to input[name="email"]".
Use the associative properties of arrays in JavaScript to get the benefits of unique field names and OOP:
var formModel = new Array();
formModel['myField'] = getMyFieldValue(); // make 'myField' index to any object
Then you can do things like:
formModel['myField'] // get the value
formModel.length; // number of fields added
for (entry in formModel) { /* loop thru entries */ }
formModel.sort([compareFunction]) // custom sort
formModel = []; // clear the model
Convert array to JSON
Any of these ArrayMDN conveniences.
Just one approach, but arrays in JS are extremely versatile and IMO underused objects in JS.

Categories

Resources