I have two data store of type dojo.data.ItemFileReadStore.One of the data store having old data and other one having new data.How can i compare these two data stores?
I call the fetch method on both of the stores and did a compare but didn't work for me.
IF a same item can be in two stores, then you could fetch all items from one store, on Complete, foreach item, otherStore.isItem(someItem) which will return a boolean :)
Have you tried that?
The format used by ItemFileReadStore is not a requirement of the dojo.data API. The
format it uses is designed to work well for the specific situations
ItemFileReadStore is used for, which are moderately sized data sets that can be easily
represented in a JavaScript Object tree.
Structure of Input Data Format
{
"label": "some attribute", // Optional attribute used to indicate which attribute on
an item should act as a human-readable label for display purposes.
"identifier": "some attribute", // Optional attribute used to indicate which
attribute on an item acts as a unique identifier for that item. If it is not defined,
then the ItemFileReadStore will simply number the items and use that number as a
unique index to the item.
"items:" [ // The array of JavaScript objects that act as the root items of the data
store
{ /* Some set of name/value attributes */ },
{ /* ... */ },
...
]
}
solution 1: in our application we have used this method:
dojo.require("dojo.json");
_equal: function(objA, objB) {
return dojo.json.stringify(objA) === dojo.json.stringify(objB);
}
the data inside objects should also have the same order, otherwise comparison will fail.
solution 2: but in dojo 1.8 they have introduced dojox/mvc/equals function.
it compares two given objects.
please also consider using dojo/store instead of deprecated dojo/data
Related
I have a table in React with data about tests which I get from API. I have to do filters on frontend and be able to join them, for example filter tests from chosen category, chosen difficulty and created before some data.
If I wanted to filter for example tests from category "Javascript" and difficulty "Junior", I should get the uri:
/api/admin/filters?filter=category:Javascript,difficulty:JUNIOR
If I wanted to filter tests for "Junior" or "Mid" I should get:
/api/admin/filters?filter=difficulty:JUNIOR,difficulty:'MID
Note apostrophe here which stands for "or".
I should also be able to filter by creation date, for example:
/api/admin/filters?filter=creationDate<2019-09-23 17:34:21,creationDate>2019-09-12 17:34:21
I wonder how I can create such queries? URLSearchParams or axios params adds parameters separated by & so I can't use it here because I have one parameter "filter" with multiple values. Or maybe I should use it and also use js replace method for replacing & for comma? I have also no idea how to add apostrophe.
I saw similar question here: https://spectrum.chat/react/general/query-string-sending-multiple-value-to-the-same-parameter~5d029da0-e7da-443d-a4b2-1529ca7b4f82
but I can't use an array in my case because I have multiple filters. I suppose I have to create object like:
options = {
difficulty: [junior, mid],
category: [javascript],
created before: 2019-09-23 17:34:21,
created after: 2019-09-12 17:34:21
}
and now how to add keys and values from such object to uri so it looks like backend expects?
Any help would be appreciated.
Encoding parameters with encodeURI before passing to axios might solve your issue.
If you need to pass parameters with special characters (like '[',']' ...etc) you should give the parameter as a string '["junior","mid"]' instead of giving parameter as an array.
(Giving as an array will just remove the brackets)
var params = '["junior","mid"]'
encodeURI(params) // it returns "%5B%22junior%22,%22mid%22%5D"
var params = ["junior","mid"]
encodeURI(params) // it returns "junior,mid"
I'm making a sortable table. The table data is from an array of objects. I need to be able to sort the array based on the properties
an object looks like this:
{
"AbsenceReservationID": 7220,
"Name": "DGM",
"Code": "ARBEIDSONGEVAL WP",
"RequestState": "Goedgekeurd",
"From": "2017-03-21T00:00:00+01:00",
}
I'm using lodash, so I can easily sort my array using the following syntax:
asc:
myArr = _.sortBy(myArr , "Name");
desc:
myArr = _.sortBy(myArr , "Name").reverse;
However I'm stuck at the last sorting method. I need to be able to undo the sort but I can't figure out a good way to do this. Here's how it would work:
1st click - sort asc
2nd click - sort desc
3rd click - remove sorting
on this property
I think the hard part is when the user sorts on mutliple properties, so for example
How can I achieve this removal of a property sort?
You basically have three choices:
Don't offer the "unsorted" option
Remember the original order (perhaps by adding a property for it), and for the "unsorted" option, sort on that property
For instance, you can add an originalIndex property:
_.forEach(myArr, function(e, i) { e.originalIndex = i; });
Then myArr = _.sortBy(myArr, "originalIndex"); will get the original order back.
Keep the original array somewhere (since _.sortBy creates a copy), and use the original array again when you want the "unsorted" version
You can use to create an original copy:
var oldArr = myArr.slice(); // gives you a new copy.
You can use oldArr after sorting.
Where are you getting the data from initially? (service)
If it is coming from a service call - would recommend simply re-calling that service and setting the data equal to the data retrieved again.
If you don't want to make a call to the service again, simply create two objects in JS sortingData and unsortedData. Then when you use the lodash method, simply apply it only to the sortingData array. On the third click, do
sortingData = unsortedData;
Where are you getting the data from initially? (manually created)
The same approach of having two objects applies here. Once the data has been created, before you allow sorting to be done, set the unsortedData to the data that you have generated. e.g.
unsortedData = data;
Should I store objects in an Array or inside an Object with top importance given Write Speed?
I'm trying to decide whether data should be stored as an array of objects, or using nested objects inside a mongodb document.
In this particular case, I'm keeping track of a set of continually updating files that I add and update and the file name acts as a key and the number of lines processed within the file.
the document looks something like this
{
t_id:1220,
some-other-info: {}, // there's other info here not updated frequently
files: {
log1-txt: {filename:"log1.txt",numlines:233,filesize:19928},
log2-txt: {filename:"log2.txt",numlines:2,filesize:843}
}
}
or this
{
t_id:1220,
some-other-info: {},
files:[
{filename:"log1.txt",numlines:233,filesize:19928},
{filename:"log2.txt",numlines:2,filesize:843}
]
}
I am making an assumption that handling a document, especially when it comes to updates, it is easier to deal with objects, because the location of the object can be determined by the name; unlike an array, where I have to look through each object's value until I find the match.
Because the object key will have periods, I will need to convert (or drop) the periods to create a valid key (fi.le.log to filelog or fi-le-log).
I'm not worried about the files' possible duplicate names emerging (such as fi.le.log and fi-le.log) so I would prefer to use Objects, because the number of files is relatively small, but the updates are frequent.
Or would it be better to handle this data in a separate collection for best write performance...
{
"_id": ObjectId('56d9f1202d777d9806000003'),"t_id": "1220","filename": "log1.txt","filesize": 1843,"numlines": 554
},
{
"_id": ObjectId('56d9f1392d777d9806000004'),"t_id": "1220","filename": "log2.txt","filesize": 5231,"numlines": 3027
}
From what I understand you are talking about write speed, without any read consideration. So we have to think about how you will insert/update your document.
We have to compare (assuming you know the _id you are replacing, replace {key} by the key name, in your example log1-txt or log2-txt):
db.Col.update({ _id: '' }, { $set: { 'files.{key}': object }})
vs
db.Col.update({ _id: '', 'files.filename': '{key}'}, { $set: { 'files.$': object }})
The second one means that MongoDB have to browse the array, find the matching index and update it. The first one means MongoDB just update the specified field.
The worst:
The second command will not work if the matching filename is not present in the array! So you have to execute it, check if nMatched is 0, and create it if it is so. That's really bad write speed (see here MongoDB: upsert sub-document).
If you will never/almost never use read queries / aggregation framework on this collection: go for the first one, that will be faster. If you want to aggregate, unwind, do some analytics on the files you parsed to have statistics about file size and line numbers, you may consider using the second one, you will avoid some headache.
Pure write speed will be better with the first solution.
From this article from Martin Hawksey, summarized:
a script bound to the Sheet is published as a web app, a form uses jQuery's $.ajax to send the request to that web app, and the web app handles the parameters into columns of the Sheet with headers matching the names of each param. (the script in this article makes use of PublicLock, which I've changed to ScriptLock)
My problem revolves around checkboxes. Inside the request, I'll see
...fruit=apple&fruit=banana&fruit=cantaloupe...
and the Apps Script will see this as well, passing e to a function handleResponse() which is triggered from doPost(e). To access the values for the parameters in the request, we use e.parameter or e.parameters. I've chosen the latter to accommodate for checkboxes and multiple values for that particular parameter.
What's not happening, though, is exactly that: only the first checkbox value is being sent through. To iterate through params, we use
for (i in headers) {
if (headers[i] == "Timestamp") {
row.push(new Date());
} else {
row.push( e.parameters[headers[i]] );
}
}
to push the values for each parameter that matches a column header into a new array that will be entered as a new row. To do that, Hawksey uses
sheet.getRange(nextRow, 1, 1, row.length).setValues([row])
I guess I'm having trouble understanding what e.parameters does and how I can access the those values. I understand that the parameters property houses the values of each name as arrays, but I can't get an array's entire list of elements to be the value for a cell in a row. Can someone help me understand what e.parameters does, and how I can better get to all of the values I need?
e.parameters is an object where the parameters are the object keys and the values are stored in an array. So, a request like this:
url?fruit=apple&fruit=orange&fruit=lime&animal=giraffe
would yield an object like this:
{'fruit': ['apple', 'orange', 'lime'], 'animal': ['giraffe']}
If you have to put all values for fruit into one cell, you might try:
e.parameters.fruit.join(',')
which will return a string with each value separated by a comma. Then, if you need to separate the values again, you could use String.split() (docs here).
I am building a dynamic form to edit data in a json object. First, if something like this exists let me know. I would rather not build it but I have searched many times for a tool and have found only tree like structures that require entering quotes. I would be happy to treat all values as strings. This edit functionality is for end users so it needs to be easy an not intimidating.
So far I have code that generates nested tables to represent a json object. For each value I display a form field. I would like to bind the form field to the associated nested json value. If I could store a reference to the json value I would build an array of references to each value in a json object tree. I have not found a way to do that with javascript.
My last resort approach will be to traverse the table after edits are made. I would rather have dynamic updates but a single submit would be better than nothing.
Any ideas?
// the json in files nests only a few levels. Here is the format of a simple case,
{
"researcherid_id":{
"id_key":"researcherid_id",
"description":"Use to retrieve bibliometric data",
"url_template" :[
{
"name": "Author Detail",
"url": "http://www.researcherid.com/rid/${key}"
}
]
}
}
$.get('file.json',make_json_form);
function make_json_form(response) {
dataset = $.secureEvalJSON(response);
// iterate through the object and generate form field for string values.
}
// Then after the form is edited I want to display the raw updated json (then I want to save it but that is for another thread)
// now I iterate through the form and construct the json object
// I would rather have the dataset object var updated on focus out after each edit.
function show_json(form_id){
var r = {};
var el = document.getElementById(form_id);
table_to_json(r,el,null);
$('body').html(formattedJSON(r));
}
A much simpler approach would be to accept a form submission and output the data in JSON format. That way, there is no need to bind variables.
The solution has arrived. JQuery now has plugins for data binding and templates.
http://www.borismoore.com/2010/09/introducing-jquery-templates-1-first.html
http://api.jquery.com/jQuery.template/
http://api.jquery.com/category/plugins/data-link/
There is another simple template engine that loads JSON data directly into the form. See http://plugins.jquery.com/project/loadJSON plugin. It works similar way as the one that Jack placed here but it uses plain HTML for template.
You can see instructions how to use it on the http://code.google.com/p/jquery-load-json/wiki/WorkingWithFormElements and live example on the http://jquery-load-json.googlecode.com/svn/trunk/edit.html?ID=17.