Using ng-repeat with keys in an array - javascript

I have an object, simulating a Cassandra database, where I retrieve its data to display it on a AngularJs app. Unfortunately, I can't make a premade header for my array because the keys are subject to change, depending on the data I'll retrieve (Here's an example of what I'm talking about):
var columnFamilyData = {
"DocInfo": {
"4c58abf5": {
"name": "coucou",
"extension": "pdf",
"size": 8751,
"type": "facture",
"repository": "archive"
},
"8cd524d7a45de": {
"name": "gerard",
"extension": "xml",
"size": 48734,
"type": "compta",
},
"5486d684fe54a": {
"name": "splendide",
"extension": "tiff",
"type": "photos",
"METADATA_A": "jambon"
}
},
"Base": {
"BASE_A": {
"name": "BASE_A",
"description": "That base is truly outrageous, they are truly, truly outrageous",
"baseMetadata_1": "METADATA_A",
"baseMetadata_2": "METADATA_B",
"baseMetadata_3": "METADATA_C"
},
},
}
As you can see, the arrays in DocInfo and Base are different, data and keys.
What I want to do is being able to use my ng-repeat to create a <th> line with the key name (for instance, Extension, of METADATA_A), but only once, since ng-repeat may duplicate this information.
I'm also providing a JSFiddle, if it can help any of you to understand my goal.
Thanks for reading and/or answering, have a great day.

Question is not totally clear, but it seems like you want "(key, val) in object" syntax.
ng-repeat="(name, age) in {'adam':10, 'amalie':12}"

Related

jquery/ajax - how to iterate through a json message with duplicate keys?

I receive with my ajax post request a message with values to display. This json response message looks like this:
{
"line": {
"name": "Google item",
"images": {
"element": {
"order": "1",
"link": "https://google.com/1.jpg",
"name": "1.jpg"
},
"element": {
"order": "2",
"link": "https://google.com/2.jpg",
"name": "2.jpg"
},
"element": {
"order": "3",
"link": "https://google.com/3.jpg",
"name": "3.jpg"
},
"element": {
"order": "4",
"link": "https://google.com/4.jpg",
"name": "4.jpg"
},
"element": {
"order": "5",
"link": "https://google.com/5.jpg",
"name": "5.jpg"
}
},
"features": {
"element": {
"name": "1",
"order": "1"
},
"element": {
"name": "2",
"order": "2"
},
"element": {
"name": "3",
"order": "3"
},
"element": {
"name": "4",
"order": "4"
}
},
"purchasing_price": "10",
"selling_price": "20",
"ftp_path": "google/item",
"description": ""
}
}
I'm in development and have not so much experience with json in jquery/ajax.
I tried this:
function parseContent(content){
$("#name").val(content.line.name);
$("#ftp_path").val(content.line.ftp_path);
$("#html_description").val(content.line.description);
$("#feature").remove();
$.each(content.line.features, function(k, v){
$("#features").append('<input type="text" class="form-control mt-3" id="feature" value="' + v.name + '" required>');
alert(v.name );
});
}
My problem is, the variable content contains just the last image und feature element. But in chrome/network I could see, the complete message has been received.
So I found out there is a parsing issue: Parsed JSON contains only the last element.
But how can I fix this in my case, to iterate through all elements?
The JSON specification says:
The names within an object SHOULD be unique.
The names in those objects are not.
SHOULD means:
that there
may exist valid reasons in particular circumstances to ignore a
particular item, but the full implications must be understood and
carefully weighed before choosing a different course.
The implications here are that every JSON parser (that I'm aware of at least) will ignore all but one of the values with duplicate names in an object.
If you really need to deal with that data then you are going to have to either track down a parser which can handle it (I'm not aware of any) or write a custom JSON parser which can (you'll also need to decide what data structure you want to generate from it because JS can't have duplicate property names in objects either). There are a number of JSON parsers on npm you might want to examine the source code of as a starting point.
A better solution would be to change whatever is generating the source data to produce a sensible format that doesn't violate a SHOULD requirement. Replacing the duplicate property names with an array for example.

How would one go about storing data after every filter over multiple queries from a database

Im using MySql as a database, and I have various types of data for animals.
How would I filter these animals multiple times, and keep the information stored for later use to be inserted in an element later on? I dont even know where to start with this, but hopefully I explained it to the best of my ability.
Would they be stored in a variable everytime I query it, or is there a better way?
You can query once and store it in a variable. Use it as you see fit.
An example :
const animals = [
{
"name": "cat",
"size": "small",
"weight": 5
},
{
"name": "dog",
"size": "small",
"weight": 10
},
{
"name": "lion",
"size": "medium",
"weight": 150
},
{
"name": "elephant",
"size": "big",
"weight": 5000
}
];
let filterArray = animals.filter((animal) => {return animal.size === 'small'});
console.log(filterArray);
Let us say the array of objects is what you get from the database. You store it and when you need, sort it with what you want as criteria.
If anyone has any other suggestions, please mention.

Strongloop Loopback: Filter by id of related Model

I have a Strongloop Loopback Node.js project with some models and relations.
The problem at hand
My problem relates how to query only those Media instances that have a relation to a certain Tag id, using the Angular SDK - while not querying Tags.media (which return Tag instances), but instead making a query somehow that returns plain Media instances.
Please read below for specific information..
Spec
Basically, I have a Model Media which has many 'tags' (model Tag). Think of a image file (Media) having various EXIF tags (Tag). Here is the relation spec (this all works as expected):
Media (media.json):
{
"name": "media",
"base": "PersistedModel",
"properties": {
"id": {
"type": "string",
"id": true
}
},
"relations": {
"tags": {
"type": "hasAndBelongsToMany",
"model": "tag"
}
}
Tag (tag.json):
{
"name": "tag",
"base": "PersistedModel",
"idInjection": true,
"properties": {
"name": {
"type": "string",
"required": true
}
},
"relations": {
"medias": {
"type": "hasAndBelongsToMany",
"model": "media"
}
},
"acls": [],
"methods": []
}
Solutions
Now, I know I could do a query like this (using Angular SDK in my example, but the syntax is the same):
injector.get('Tag').find({
'filter': {
'include': 'medias',
'where': {'id': <mytagid>}
}
});
My problem with this approach is, that I receive 1 (one) Tag instance with attached Media instances. This disrupts why whole workflow as I deal only with Media instances.. i just want to filter by Tag id, not bother about Tag at all.
Bottom line
If I see the API explorer (/explorer/), the return value of GET /api/tags/<myTagID>/medias is exactly what I need - an array of Media objects - but how to query them exactly like this using the Angular SDK (lb_services)?
I had a similar problem. One recommendation is to open the lb-services.js and try to find: /tags/:id/medias or something similar. Then you will find a comment like this: // INTERNAL. Use Tags.medias() instead. Or something similar. So that is the method that you should call. Do not call the "prototype$__get....." methods.
Then just call what it says there I suppose: Tag.medias({id:})
Other suggestions:
As you said in your description Media has many Tags. So why not use just
{
"name": "media",
"base": "PersistedModel",
"properties": {
"id": {
"type": "string",
"id": true
}
},
"relations": {
"tags": {
"type": "hasMany", <---------- hasMany
"model": "tag",
"foreignKey": "tagId" <---FK name
}
}
and
for the tags just belongsTo as type.
{
"name": "tag",
"base": "PersistedModel",
"idInjection": true,
"properties": {
"name": {
"type": "string",
"required": true
}
},
"relations": {
"medias": {
"type": "belongsTo",
"model": "media",
"foreignKey": "mediaId" <---FK name
}
},
"acls": [],
"methods": []
}
But really I don't think this is the problem because you said when you request GET /api/tags/<myTagID>/medias it returns what you want.
Then, in AngularJS you can use:
Media.tags({id:<mediaId>})
for media/:id/tags
and for the other side try:
Tag.medias({id:<tagId>})
Tag.find({
filter:{
where:{mediaId: <mediaId>} <----mediaId comes from FK name
}
})
In this case both are persistent models there is no problems, I had permission problems when doing a similar thing with data that extends User type. But that is another story...
Hope this is helpful, I changed some stuff from a similar app that I am doing and hope not making so many errors when adapting to your code...

Convert Excel file to JSON: design of JSON code check

I want to convert the data from an Excel file to a JSON file. However, I'm not sure about the design of my JSON code (i.e. is it organized in a proper way in order to process it easily?)
I will use this JSON file with D3.js.
This a small part of my Excel file:
I'd like to convert this data into a JSON file in order to use it with D3.js. This is what I have so far:
So my question is: is this a good design (way) for organizing the data in order to use it with D3.js?
This is a sample output:
Thanks in advance!
This is a somewhat subjective question, but from my experience, there is a better way:
Since you're working in d3, you're probably doing something like this:
d3.selectAll('div')
.data(entities)
.enter()
.append('div')
...
So you want entities to be an array. The question is what are your entities? Is there a view where entities are all the countries in the world? Is there a view where entities are all the countries plus all the regions plus the whole world? Or, are all the views going to be simply all the countries in a selected region, not including the region itself?
The unless the JSON structure you're proposing matches the combinations of entities that you plan to display, your code will have to do a bunch of concat'ing and/or filtering of arrays in order to get a single entities array that you can bind to. Maybe that's ok, but it will create some unnecessary amount of coupling between your code and the structure of the data.
From my experience, it turns out that the most flexible way (and also probably the simplest in terms of coding) is to keep the hierarchy flat, like it is in the excel file. So, instead of encoding regions into the hierarchy, just have them in a single, flat array like so:
{
"immigration": [
{
"name": "All Countries"
"values: [
{ "Year": ..., "value": ... },
{ "Year": ..., "value": ... },
...
]
},
{
"name": "Africa"
"values: [
{ "Year": ..., "value": ... },
{ "Year": ..., "value": ... },
...
]
},
{
"name": "Eastern Africa"
"continent": "Africa"
"values": [
{ "Year": ..., "value": ... },
{ "Year": ..., "value": ... },
...
]
},
{
"name": "Burundi"
"continent": "Africa"
"region": "East Africa"
"values": [
{ "Year": ..., "value": ... },
{ "Year": ..., "value": ... },
...
]
},
{
"name": "Djibouti"
"continent": "Africa"
"region": "East Africa"
"values": [
{ "Year": ..., "value": ... },
{ "Year": ..., "value": ... },
...
]
},
...
]
}
Note that even though the array is flat, there is still a hierarchy here -- the region and sub-region properties.
You'll have to do a bit of filtering to extract just the countries/regions you want to show. But that's simpler than traversing the hierarchy you're proposing:
var africanEntities = data.immigration.filter(function(country) {
return country.continent == "Africa";
}); // Includes the region "East Africa"
var justCountries = data.immigration.filter(function(country) {
return country.continent != null && country.region != null;
});
Also, d3 has the awesome d3.nest(), which lets you turn this flat data into hierarchical one with little effort:
var countriesByContinent = d3.nest()
.key(function(d) { return d.continent; })
.map(data.immigration);
var africanEntities = countriesByContinent['Africa'];
Hope that helps....

Set the custom properties in joining model using LoopBacks HasManyThrough

I am trying to set up a many to many relationship in LoopBack 2.1.2
http://docs.strongloop.com/display/LB/HasManyThrough+relations
I tried to POST /api/patients/:patientId/physicians to create a new physician which links the patientId to the new physician, but does not set the appointmentDate in the appointment model.
Is there one API call to create this in one transaction?
What is the best way to add a new physician to a patient and setting the appointmentDate?
Do I have to create my own RESTFUL API call?
These are my json models
filename: appointment.json
{
"name": "appointment",
"base": "PersistedModel",
"relations": {
"patient": {
"type": "belongsTo",
"model": "patient"
},
"physician": {
"type": "belongsTo",
"model": "physician"
}
},
"properties": {
"appointmentDate": {
"type": "string"
}
},
"validations": [],
"acls": [],
"methods": []
}
filename: patient.json
{
"name": "patient",
"base": "PersistedModel",
"relations": {
"physicians": {
"type": "hasMany",
"model": "physician",
"through": "appointment"
}
},
"properties": {
"name": {
"type": "string"
}
},
"validations": [],
"acls": [],
"methods": []
}
filename: physician.json
{
"name": "physician",
"base": "PersistedModel",
"relations": {
"patients": {
"type": "hasMany",
"model": "patient",
"through": "appointment"
}
},
"properties": {
"name": {
"type": "string"
}
},
"validations": [],
"acls": [],
"methods": []
}
Disclaimer: I am a LoopBack developer working for StrongLoop.
Is there one API call to create this in one transaction?
No, there is no such API at the moment.
What is the best way to add a new physician to a patient and setting the appointmentDate?
You have to send two requests: The first one to create a physician (POST /physicians), the second one to create the appointment (POST /appointments).
Alternatively, you can use "Patient hasMany appointments" instead of "Patient hasMany physicians through Appointment", in which case the appointment can be added via
POST /patients/:patientId/appointments`
You will still have to create the physician first.
Do I have to create my own RESTFUL API call?
You can certainly do that, although I personally don't understand why two requests are a problem in this case. The operation "create a new physician with an appointment for the given patient" looks weird to me. Two steps ("create a new physician", and some time later "make an appointment") make more sense to me.
However, if you have a good example where it makes sense to create both records in one request, then please open a github issue in strongloop/loopback to discuss this further.
More info
At the moment, the "hasMany through" relation is tuned for the purpose of "hasAndBelongsToMany" relation, where the "through" model is just a container for the two id properties (foreign keys). That's the reason why the relation methods like POST /api/patients/:patientId/physicians do not support "through" properties like "appointmentDate".
I have created a github issue loopback#466 to discuss how to improve this part of LoopBack, feel free to comment there.
There is also a bug in loopback-explorer (#39), where the UI suggest that POST /patients/{id}/physicians is expecting an Appointment, even though the implementation expects a Physician instead.

Categories