I can't manage to create 3rd level of dijit.Tree - json

I wanted to create a 3 level dijit.Tree, like that:
-root
|
--level1
|
--level2
I thought it would be really simple since there's a code snippet in this tutorial (example 1). But somehow I manage to fail.
This is my dojo code (variable names are in Polish, I hope it's not a problem):
modelRaportow = new dijit.tree.ForestStoreModel({
store: new dojo.data.ItemFileReadStore({
url: "logika/getJSON/getStatusRaportow.php"
}),
query: {typ: 'galaz'},
rootId: 'statusRaportuRoot',
rootLabel: 'Status raportu',
childrenAttrs: 'raporty'
});
drzewoRaportow = new dijit.Tree({
openOnClick: true,
model: modelRaportow,
showRoot: true,
persist: false
}, "target-status-raportow");
drzewoRaportow.startup();
This is my JSON returned by logika/getJSON/getStatusRaportow.php (again, names are in Polish):
{
"identifier":"id",
"label":"status",
"items": [
{"id":0,"status":"zaakceptowane","typ":"galaz"
"raporty":[{"_reference":1},{"_reference":2},{"_reference":3}]},
{"id":1,"data":"24-10-2011","wykonujacy":"cblajszczak","idKlienta":3,"status":"Raport0","typ":"lisc"},
{"id":2,"data":"24-10-2011","wykonujacy":"cblajszczak","idKlienta":1,"status":"Raport1","typ":"lisc"},
{"id":3,"data":"24-10-2011","wykonujacy":"cblajszczak","idKlienta":3,"status":"Raport2","typ":"lisc"},
{"id":4,"status":"odrzucone","typ":"galaz"
"raporty":[{"_reference":5},{"_reference":6},{"_reference":7}]},
{"id":5,"data":"24-10-2011","wykonujacy":"cblajszczak","idKlienta":1,"status":"Raport3","typ":"lisc"},
{"id":6,"data":"24-10-2011","wykonujacy":"cblajszczak","idKlienta":3,"status":"Raport4","typ":"lisc"},
{"id":7,"data":"24-10-2011","wykonujacy":"cblajszczak","idKlienta":3,"status":"Raport5","typ":"lisc"}
]}
And finally, this is what I'm getting: img - root node and lvl 1 nodes returned by query, no child nodes.
The question is - where is my mistake? Can anyone see it?

You have no comma between the typ and raporty value pair.

I have a partial answer: by stepping through the code in a similar situation, I've discovered that it expects childrenAttrs to be an array, so it should be:
childrenAttrs: ['raporty']
but I still cannot get the third level to appear in my case.

Related

ImmutableJs - compare objects but for one property

I am converting a shopping basket to an immutable structure.
Is there an easy way with immutablejs to see if an immutable object already exists within an immutable list EXCEPT for one object property 'quantity' which could be different? List example:
[{
id: 1,
name: 'fish and chips',
modifiers: [
{
id: 'mod1',
name: 'Extra chips'
}
],
quantity: 2
},{
id: 2,
name: 'burger and chips',
modifiers: [
{
id: 'mod1',
name: 'No salad'
}
],
quantity: 1
}]
Now, say I had another object to put in the list. But I want to check if this exact item with modifiers exists in the list already? I could just do list.findIndex(item => item === newItem) but because of the possible different quantity property then it wont work. Is there a way to === check apart from one property? Or any way to do this without having to loop through every property (aside from quantity) to see if they are the same?
Currently, I have an awful nested loop to go through every item and check every property to see if it is the same.
Well this should work-
list.findIndex(item => item.delete("quantity").equals(newItem.delete("quantity"))
The equals method does deep value comparison. So once you delete the quantity, you are comparing all values that matter.
PS: please ignore code formatting, I am on SO app.
PPS: the above code is not optimal, you should compare a pre-trimmed newItem inside the arrow function instead of trimming it there.

How to parse the external json in gulp-jade?

I'm using jade templates for my templating system, passing a json file in as the jade locals via my gulpfile.js, but I can't seem to deep dive into the json. I feel like I'm overlooking something basic, but can't find an example online anywhere.
gulpfile.js:
Passes the json file into jade
gulp.task('html', function() {
gulp.src('./markup/*.jade')
.pipe(jade({
pretty: true,
locals: JSON.parse( fs.readFileSync('./markup/data/website_data.json', { encoding: 'utf8' }) )
}).on('error', gutil.log))
.pipe(gulp.dest('../'))
});
Then in my jade, I just pass the locals into a variable for the sake of readability.
- var employees = locals
And I can loop through json that is one level deep:
jade:
for employee in employees
if employee.Tier === 'Founder'
li
button(data-bio="#{employee.LastName.toLowerCase()}")
img(src="/public/img/employees/#{employee.FirstName.toLowerCase()}-#{employee.LastName.toLowerCase()}.jpg", alt="#{employee.FirstName} #{employee.LastName} | #{employee.Title}")
strong #{employee.FirstName} #{employee.LastName}
| #{employee.Title}
json:
[
{
"FirstName":"John",
"LastName":"Doe",
"Title":"Strategist",
"Tier":"Founder",
"Description":"",
"Email":"",
"Links":""
},
...
]
But that has only worked for me if the items I loop through are in the root, as soon as I make the json one level deeper, I can't get it to work based on the key. I want to make the json deeper so I can different sections of a site in it instead of just the employees.
[{
"employees": [
{
"FirstName":"Jason",
"LastName":"Bellinger",
"Title":"Lorem Ipsum",
"Tier":"",
"Description":"",
"Email":"",
"Links":""
},
...
]
}]
I tried a few different approaches to to dig into the json and have failed thus far.
ATTEMPT 1: adjust the variable call and keep the same loop
- var employees = locals.employees
And I get 'Cannot read property 'length' of undefined' in the terminal running $gulp watch
Also try:
- var employees = locals['employees']
to the same result.
ATTEMPT 2: don't use the var and call locals directly in my loop
for employee in locals.employees
AND
for employee in locals["employees"]
And I end up with the same error.
ATTEMPT 3:
keep the var and adjust the loop
- var employees = locals
...
for employee in employees
li #{employee.LastName}
Then I don't get an error in Terminal, but I don't get any content. It produces one empty li.
So then, I try to go a layer deeper in the loop with:
for employee in employees[0]
li #{employee.LastName}
AND
for employee in employees['employees']
li #{employee.LastName}
AND I still get no error and one empty li
I've parsed enough json in my day and jade seems simple enough, I have to be overlooking something basic. Someone please humble me.
I also dabbled in gulp-data, but I'm getting the data into jade with my approach, so I think it's my approach in jade...
You need to access the array inside you locals variable.
The length of local = 1 and that is the entire array of employees.
You'll need to set employees = to the array inside of the locals variable with:
"- var employees = locals[0].employees"
I knew it was something basic. I reverted everything back to the original setup and changed the var and this is working.
- var employees = locals[0]['employees']
Truth be told, I thought I already tried this, but went back and tried again...

Ember many-to-many Ids are not included in JSON payload on post?

I have a meeting and a sales-rep models, The relation is ManyToMany.
The problem is, When I want to create a New meeting, and assign existing salesReps to it (They are already saved to the store), But The salesReps IDS are not included in The post action caused by model.save() (not even an empty array), To make it more clear, Here is what my code looks like:
meeting.coffee:
Meeting = DS.Model.extend
client: DS.belongsTo('client')
salesReps: DS.hasMany('sales-rep')
memo: DS.attr('string')
startDate: DS.attr('date')
duration: DS.attr()
sales-rep.coffee:
SalesRep = DS.Model.extend
meetings: DS.hasMany('meeting')
firstName: DS.attr('string')
lastName: DS.attr('string')
title: DS.attr('string')
meetings/new.coffee (the save action am using inside new meeting controller):
save: ->
meeting = #get('model')
meeting.set('client', #get('client'))
meeting.get('salesReps').pushObjects(#get('salesReps.content'))
meeting.save().then =>
#transitionToRoute 'meetings'
the JSON payload: ( POST http://localhost:4200/api/meetings)
meeting: {memo: null, start_date: null, duration: "00:15", client_id: null}
client_id: null
duration: "00:15"
memo: null
start_date: null
No matter what, There is no ANY trace of the salesReps ids in the payload!!
What I tried so far:
Setting the hasMany relation in the meeting model only.
Setting {async: true}, and then {async: false}, on both SalesRep, And
then on one of them
spending almost 2 days googling and reading all related posts in here
with no luck
Any Help/hints/Advice, Is highly appreciated
I will write the solution I found after endless reading and researching, I will write the full details, and trial/failure i've been through, Because no one, no one EVER should have to spend more than 3 days trying to fix something like that!!
I am using Ember-cli, So, there are a files/directories structure am following:
First attempt:
Trying all combinations of async: true, embedded true and what not.
Result, No luck
Second attempt:
in app/serializers/ I added the following serializer file:
meeting.coffee
`import DS from "ember-data"`
`import Ember from "ember"`
`import config from '../config/environment'`
get = Ember.get
serializer = DS.RESTSerializer.extend
serializeHasMany: (record, json, relationship) ->
rel_ids = get(record, relationship.key).map (rel) -> get(rel, 'id') || []
json["#{relationship.key.underscore().singularize()}_ids"] = rel_ids
json
`export default serializer`
result:
Adding this serializer, And I finally was able to send sales_rep_ids:[] array to the controller! and I could confirm that the server is saving the accociations as required.
But, When listing meetings, I was not able to list the associated salesReps, So, I checked the JSON am getting from the server, and it was correct (salesReps Ids were included!) But still not listed in Ember
Third Attempt:
After more reading and endless head-banging-against-the-wall, Changing ONE line fixed the problem!:
in app/serializers/meeting.coffee
change serializer = DS.RESTSerializer.extend to
serializer = DS.ActiveModelSerializer.extend
And Voila! Saved to the back-end, And listed correctley as association in ember!
This solution is a result of 3+ of constant headache, Am posting it here hopefully it might be helpful to someone facing the same problem, I can't claim that it's my own solution, but, It's the result of reading many people's code.
am not sure if it's the Ember way to do so, So, Any suggestions, Improvements Ideas and thought are welcome.

CSV Parser through angularJS

I am building a CSV file parser through node and Angular . so basically a user upload a csv file , on my server side which is node the csv file is traversed and parsed using node-csv
. This works fine and it returns me an array of object based on csv file given as input , Now on angular end I need to display two table one is csv file data itself and another is cross tabulation analysis. I am facing problem while rendering data, so for a table like
I am getting parse responce as
For cross tabulation we need data in a tabular form as
I have a object array which I need to manipulate in best possible way so as to make easily render on html page . I am not getting a way how to do calculation on data I get so as to store cross tabulation result .Any idea on how should I approach .
data json is :
[{"Sample #":"1","Gender":"Female","Handedness;":"Right-handed;"},{"Sample #":"2","Gender":"Male","Handedness;":"Left-handed;"},{"Sample #":"3","Gender":"Female","Handedness;":"Right-handed;"},{"Sample #":"4","Gender":"Male","Handedness;":"Right-handed;"},{"Sample #":"5","Gender":"Male","Handedness;":"Left-handed;"},{"Sample #":"6","Gender":"Male","Handedness;":"Right-handed;"},{"Sample #":"7","Gender":"Female","Handedness;":"Right-handed;"},{"Sample #":"8","Gender":"Female","Handedness;":"Left-handed;"},{"Sample #":"9","Gender":"Male","Handedness;":"Right-handed;"},{"Sample #":";"}
There are many ways you can do this and since you have not been very specific on the usage, I will go with the simplest one.
Assuming you have an object structure such as this:
[
{gender: 'female', handdness: 'lefthanded', id: 1},
{gender: 'male', handdness: 'lefthanded', id: 2},
{gender: 'female', handdness: 'righthanded', id: 3},
{gender: 'female', handdness: 'lefthanded', id: 4},
{gender: 'female', handdness: 'righthanded', id: 5}
]
and in your controller you have exposed this with something like:
$scope.members = [the above array of objects];
and you want to display the total of female members of this object, you could filter this in your html
{{(members | filter:{gender:'female'}).length}}
Now, if you are going to make this a table it will obviously make some ugly and unreadable html so especially if you are going to repeat using this, it would be a good case for making a directive and repeat it anywhere, with the prerequisite of providing a scope object named tabData (or whatever you wish) in your parent scope
.directive('tabbed', function () {
return {
restrict: 'E',
template: '<table><tr><td>{{(tabData | filter:{gender:"female"}).length}}</td></tr><td>{{(tabData | filter:{handedness:"lefthanded"}).length}}</td></table>'
}
});
You would use this in your html like so:
<tabbed></tabbed>
And there are ofcourse many ways to improve this as you wish.
This is more of a general data structure/JS question than Angular related.
Functional helpers from Lo-dash come in very handy here:
_(data) // Create a chainable object from the data to execute functions with
.groupBy('Gender') // Group the data by its `Gender` attribute
// map these groups, using `mapValues` so the named `Gender` keys persist
.mapValues(function(gender) {
// Create named count objects for all handednesses
var counts = _.countBy(gender, 'Handedness');
// Calculate the total of all handednesses by summing
// all the values of this named object
counts.Total = _(counts)
.values()
.reduce(function(sum, num) { return sum + num });
// Return this named count object -- this is what each gender will map to
return counts;
}).value(); // get the value of the chain
No need to worry about for-loops or anything of the sort, and this code also works without any changes for more than two genders (even for more than two handednesses - think of the aliens and the ambidextrous). If you aren't sure exactly what's happening, it should be easy enough to pick apart the single steps and their result values of this code example.
Calculating the total row for all genders will work in a similar manner.

Iterating through couchbase keys without a view

In couchbase, I was wondering if there was a way - WITHOUT using a view - to iterate through database keys. The admin interface appears to do this, but maybe its doing something special. What I'd like to is make a call like this to retrieve an array of keys:
$result = $cb->get("KEY_ALBERT", "KEY_FRED");
having the result be an array [KEY_ALEX, KEY_BOB, KEY_DOGBERT]
Again, I don't want to use a view unless there's no alternative. Doesn't look like its possible, but since the "view documents" in the admin appears to do this, I thought i'd double-check. I'm using the php interface if that matters.
Based on your comments, the only way is to create a simple view that emit only the id as par of the key:
function(doc, meta) {
emit( meta.id );
}
With this view you will be able to create query with the various options you need :
- pagination, range, ...
Note: you talk about the Administration Console, the console use an "internal view" that is similar to what I have written above (but not optimized)
I don't know about how couchbase admin works, but there are two options. First option is to store your docs as linked list, one doc have property (key) that points to another doc.
docs = [
{
id: "doc_C",
data: "somedata",
prev: "doc_B",
next: "doc_D"
},
{
id: "doc_D",
data: "somedata",
prev: "doc_C",
next: "doc_E"
}
]
The second approach is to use sequential id. You should have one doc that contain sequence and increment it on each add. It would be something like this:
docs = [
{
id: "doc_1",
data: "somedata"
},
{
id: "doc_2",
data: "somedata"
}
...
]
In this way you can do "range requests". To do this you form array of keys on server side:
[doc_1, doc_2 .... doc_N]and execute multiget query. Here is also a link to another example
The couchbase PHP sdk does support multiget requests. For a list of keys it will return an array of documents.
getMulti(array $ids, array $cas, int $flags) : array
http://www.couchbase.com/autodocs/couchbase-php-client-1.1.5/classes/Couchbase.html#method_getMulti