How to add an id property to a File? - javascript

I have an input to upload files. The uploaded files are shown as list displaying the file.name. When I add an id-property to a file it loses all it's properties except the path property. How can I add an id properly?
const fileWithId = {...uploadedFile, id: "myIdName"} //does not work

You can't copy File objects, they're largely-opaque data structures other than the specified properties, which don't include an id.
You might be able to just assign an id property (since most objects in the browser environment are extensible, meaning you can add properties to them), but I wouldn't recommend it. The definition of the File object changes over time, and you never know, it might get an id property that means something different from your id.
What you do instead will depend entirely on what you expect to do with the File. For instance, if this is just for client-side information, you might make your list a list of objects with id and file properties, where file is the original File object:
const fileWithId = {id: "myIdName", file: uploadedFile};

Related

In Javascript/Typescript can I recursively deserialize a Protobuf object with nested fields while omitting optional fields which are not present?

I am using protocol buffers for sending changed state in a multiplayer game and I am wondering if there as a better way to unpack an object with nested fields that may or may not be present. I want non-present fields to be completely omitted, rather than listed as their default value.
Currently I am checking each field for presence by using the .hasField() methods on each property of the object. If that field exists and it has nested properties I have to use the .hasField() method of those properties, and so on. I leads me to write code like what is below, which I find to be verbose and error prone.
What I really want is something like the provided .toObject() method on the deserializedMessage, but with a slightly different behavior. The .toObject() includes all the fields (if they were not set they are the default values). I don't want optional fields which were not set to be shown because I only want fields which have changed so I can apply the changes to the client's game state.
Is there any built-in feature of protobuf or npm package that can accomplish this?
I am using proto3 and ts-protoc-gen to compile the .proto file into Typescript and Javascript
What I'm currently doing:
const playerProto = PlayerProto.deserializeBinary(binaryData)
const unpackedDeltas: IUnpackedPlayerDeltas = {};
const destination = playerProto.hasDestination() ? playerProto.getDestination() : null;
if (destination) unpackedDeltas.destination = new Point(destination.getX(),destination.getY());
if (playerProto.hasIsselected()) unpackedDeltas.isSelected = playerProto.getIsselected();
// etc for each property and their nested properties...
return unpackedDeltas;
What I would like:
const playerProto = PlayerProto.deserializeBinary(binaryData)
const unpackedDeltas = playerProto.toDeepObjectWithoutAbsentFields() // returns an object containing only the fields that were set on the server. does not include any default values for fields that were not set.

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.

Preventing a section of html from referring to other tags / elements on the same page

I have a php webpage that includes some graphical dials created with css and javascript (and an ajax call). Each dial is added to the webpage using:
$_SESSION['info'] = dial1 Specific info.
include 'dial.php';
$_SESSION['info'] = dial2 Specific info.
include 'dial.php';
Inside dial.php, there is a section that analyzes the SESSION variable to adjust an arm on the dial, and creates the dials circular shape with css. The problem I'm trying to solve is the second dial is a copy of the first dial, and not distinct.
How can I make the above code force each "include 'dial.php'" to operate independently from each other and not interact with each other (since the variables, function names, and css names are the same for each dial).
Best Regards
you can not add two different object into one variable !
make your session variable as an array like below :
$_SESSION['info'][1] = dial1 Specific info.
include 'dial.php';
$_SESSION['info'][2] = dial2 Specific info.
include 'dial.php';
for a better answer , put your dial.php code , I'll update my answer
The session variable can hold many types of data but you need to structure the session variable in a different manner to your initial code. If you were to assign an object as the value ( as below ) you can access the right piece of information easily using the object notation shown below.
$_SESSION['info']=(object)array(
'dial_1' => 'dial1 Specific info',
'dial_2' => 'dial2 Specific info'
);
then access the individual info by
$info=$_SESSION['info']->dial_1;
So I ended up using dynamic html tag ids, function names, and variables. It seems to be working out fine.

IndexedDB Fails when adding objects that contain element references

I'm writing an application for Google Chrome (targeted audience is an internal team) that allows a user to manipulate elements from within an iframe. The user is able to use her mouse to select DOM elements and to perform various actions to them, such as changing colors, fonts, etc.
I'm using a nodeIterator method to select only elements that have IDs or class names. Then for each of those elements, I add some element-specific properties to an object, and push that object to an array. Then, I open an IndexedDB database and add each object in the array to the database.
My problem is this: Everything works fine so long as I don't include a reference to the element in the object.
// Works fine
array.push({
width : currentNode.offsetWidth,
height : currentNode.offsetHeight,
top : currentNode.style.top;
left : currentNode.style.left;
});
// Doesn't work
array.push({
elem : currentNode,
width : currentNode.offsetWidth,
height : currentNode.offsetHeight,
top : currentNode.style.top;
left : currentNode.style.left;
});
Google chrome fails silently (nothing in the console at all) after trying to add the first element to the IndexedDB store.
My question is this: Has anyone else experienced this behavior and is this a browser-specific bug?
I'll distill my code to JSfiddle tomorrow. Thanks in advance.
IndexedDB store structured clone of your object. Basically your data will converted into JSON object, these exclude Element or Node data type.
However fail silently is not an expected behaviour. Accordingly to the structured clone algorithm, it should throw DataCloneError.
Is it necessary to save the DOM element? Can you just save the ID of the DOM element and retrieve the element back by its ID?
The indexeddb is only capable of storing data that doesn't have circular references. There is maybe one thing you can try. Sometime ago I wrote a blog post on how you can serialize and deserialize functions to JSON. Maybe this can help you, but I would advace you not to store complete elements unless there is no other option. This will add a lot of unnecessary data into your database, and it's possible you'll lose information when serializing to JSON.
You should get an exception in chrome (I just tried on Chrome 23) from the put() itself, which means if you have an onerror handler, it won't get called because the exception gets called first:
i.e. if you have
req = db.transaction("foo", "readwrite").objectStore("foo").put({...data with dom nodes })
req.onsuccess = ...
req.onerror = ...
The exception will be thrown by the first line.

Categories

Resources