AngularJS Data Structure: Client side or API? - javascript

I have a prototype solution in AngularJS and it is working with the following data structure:
$scope.clients = [
{ client:"Client1", projects:[
{ project: "Project1", items:[
{ item: "This is the first item" },
{ item: "This is the second item" }
]},
{ project: "Project2", items:[
{ item: "This is the third item" },
{ item: "This is the fourth item" }
]}
]},
{ client:"Client2", projects:[
{ project: "Project4", items:[
{ item: "This is the fifth item" },
{ item: "This is the sixth item" }
]}
]}
];
I am looking to implement the back end and I am not sure if the API should serve the above nested data structure to the client or if it should serve a flat structure of items and then the AngularJS client app then creates the nested structure. Here is an example of the flat structure that the API would serve:
[
{ client: "Client 1", project: "Project 1", item: "This is the first item." },
{ client: "Client 1", project: "Project 1", item: "This is the second item.", },
{ client: "Client 1", project: "Project 2", item: "This is the third item.", },
{ client: "Client 2", project: "Project 4", item: "This is the fourth item.", }
];
What is the best approach for this? Additionally, is there any good references to for API design?

If you're working with JSON, then the "application/hal+json" standard is definitely worth looking at.
You can read all details right here: https://datatracker.ietf.org/doc/html/draft-kelly-json-hal-05
There is also a very good presentation by Matthew Weier O'Phinney with sample code on how to use this with a PHP backend: http://www.zend.com/en/resources/webinars/ (scroll down to the "Build RESTful ZF2 Applications" webinar).
Basically it is a set of conventions that allow linking and embedding of data within your response, which is exactly what you need here.
Hope that helps!

I generally find it helpful to not be translating my API responses to different formats throughout my application. If the nested structure is useful on your page, and it will continue to be useful elsewhere as well, I would just stick with it. You don't want to be in a situation where you are transforming an API response from one format to another on every page you use it on, so go with something that is cohesive, and simple to understand.
IMO, the nested structure looks better because you don't have to make groupings and associations on the front end. I tend to prefer when my API responses require very little if any "massaging" to work within the context of my page, if possible.
As far as API design goes, if you are looking for some standards this question's answer has some good references for standard API designs and response formats.

Related

how to navigate nested objects of unknown depth?

Im making a notetaking app and Ive decided to store all the notes and structure in JSON file. On javascript, I get the JSON with AJAX, parse it and output it on the website.
My note structure is array of objects that can be nested, like this (if it is a note, it has a "content" attribute, if it is a folder, it has an array of objects (can be empty array too if the folder should me empty):
data {
entries = [
{
name: "Some note",
content: "This is a test note"
},
{
name: "folder",
children: [
{
name: "Bread recpie",
content: "Mix flour with water..."
},
{
name: "Soups",
children: [
{
name: "Pork soup",
content: "Add meat, onion..."
},
{
name: "Chicken soup"
content: "....."
}
]
}
]
}
]
}
To list the root directory, its simple, i just loop through the array as it only outputs the top-level records:
for (entry of data.entries) {
const li = document.createElement("li");
li.textContent = entry.name;
if (entry.children) {
li.className = "folder";
} else {
li.className = "file";
}
loop.appendChild(li);
}
But what about the folders? How should I proceed in listing the folders if the depth of nesting is unknown? And how do I target the specific folder? Should I add unique IDs to every object so i can filter the array with them? Or should I store some kind of depth information in a variable all the time?
You're making this more difficult for yourself by saving data to a JSON file. That is not a good approach. What you need to do is design a database schema appropriate for your data and create an API that outputs a predictable pattern of data that your client can work with.
I would suggest having a Folder resource and a Note resource linked through a one-to-many relationship. Each Folder resource can have many associated Note entries, but each Note has only one Folder that it is linked to. I suggest using an ORM, because most make it easy to eager load related data. For instance, if you choose Laravel you can use Eloquent, and then getting all notes for a folder is as easy as:
$folderWithNotes = Folder::with('notes')->where('name', 'school-notes')->get();
Knowing PHP is beside the point. You should still be able to see the logic of that.
If you create a database and build a server-side API to handle your data, you will end up with JSON on your client side that has a predictable format and is easy to work with.

JIRA API create issue and subtask in a single api call

I am working on creating a script where I want to create a jira ticket along with several sub tasks. I am able to figure out creation of issue as well as sub tasks in different API calls with the following payload:
{
"fields": {
"project":
{
"key": "TEST"
},
"summary": "TEST summary",
"description": "TEST Description",
"issuetype": {
"name": "Bug"
}
}
}
Create a sub-task and attach it to the issue from above API call:
{
"fields":
{
"project":
{
"key": "TEST"
},
"parent":
{
"key": "TEST-1"
},
"summary": "Sub-task of TEST-1",
"description": "TEST-1 desc",
"issuetype":
{
"id": "5"
}
}
}
However, I want to do both in a single API call. Is it something that can be done ?
The Jira REST API does not offer such kind of operation. It does offer a bulk endpoint for creating multiple issues, but you can't define something like "issue one is the parent issue of issue two which is declared further down in the JSON file".
You have to use two different API calls:
Create your parent issue by using POST /rest/api/2/issue and save the issue key from the response.
Create the sub tasks with a bulk operation using POST /rest/api/2/issue/bulk.
The links are referring to the REST API docs for Jira Server, but the same is possible with the REST API in Jira Cloud. Only the authentication method is different.

How to combine mutable JSON objects using PHP or JS?

The Project
I'm currently using FullCalendar to display a constantly changing calendar containing various information. When the user clicks on a day, a modal appears displaying a title, description, and links to files.
My current JSON object looks like:
{
"title": "myTitle",
"start": "2015-12-18T09:00:00",
"end": "2015-12-18T10:00:00",
"item_number": "1",
"description": "Test Document",
"items":[
{
"docName":"Document 1",
"docUrl":"docName.pdf"
},
{
"docName":"Document 2",
"docUrl":"docName-2.pdf"
},
{
"docName":"Document 3",
"docUrl":"docName-3.pdf"
},
],
"id": 0
}
The setup:
There are three teams:
Schedulers - This team modifies the schedule, then notifies me to edit the JSON file, updating the calendar.
Editors - This team creates then sends the documents to me to upload to the server and modify the JSON file.
Developers - This team puts everything together. Some days, you might have 60-90 edits throughout the day.
Currently, the JSON document is manually modified by the developers while we test.
My Plan:
Since the schedulers are not very tech-savvy, what I'm doing is having them modify a Google Spreadsheet that is published as a CSV and converted to JSON through PHP. This creates the following JSON object:
{
"title": "myTitle",
"start": "2015-12-18T09:00:00",
"end": "2015-12-18T10:00:00",
"item_number": "1",
"description": "Test Document"
}
The editors will create their documents and upload using Dropzone. A JSON object is created referencing the file(s):
"items":[
{
"docName":"Document 1",
"docUrl":"docName.pdf"
},
{
"docName":"Document 2",
"docUrl":"docName-2.pdf"
},
{
"docName":"Document 3",
"docUrl":"docName-3.pdf"
}
]
The two JSON objects are combined and an ID is assigned:
{
"title": "myTitle",
"start": "2015-12-18T09:00:00",
"end": "2015-12-18T10:00:00",
"item_number": "1",
"description": "Test Document",
"items":[
{
"docName":"Document 1",
"docUrl":"docName.pdf"
},
{
"docName":"Document 2",
"docUrl":"docName-2.pdf"
},
{
"docName":"Document 3",
"docUrl":"docName-3.pdf"
}
],
"id": 0
}
When changes occur – maybe there's a change to a document's name, documents are added or removed, or dates change – the individual JSON objects are re-created and re-combined.
The JSON file has hundreds of objects and, what I'm having trouble with is inserting the "items" key in the correct object. For instance, objects with IDs 0-5 are created. "items" of ID=0 is modified. Update "items" of ID=0 and not 1-5.
The Question(s)
Using PHP or JavaScript, how can I link these two JSON objects correctly?
Would it be better to feed all of this information into a database (MySQL) and then construct the JSON file?

Best way to store json object from rest api in an offline cordova app

I'm building an AngularJS application wrapped with Cordova for Android and iOS.
All my datas come from my rest API.
I have urls like my.api/groups/1/items to get the list of items
[
{
id: 5,
type: "foo",
title: "Item 5",
group: 1,
body: "<p>Some content</p> ",
img: "http://my.website/images/item5.jpg"
},
{
id: 6,
...
}
]
and my.api/items/5 to get a specific item
{
id: 5,
type: "foo",
title: "Item 5",
group: 1,
body: "<p>Some content</p> ",
img: "http://my.website/images/item5.jpg"
}
I retrieve my datas with restangular and it works perfectly
Restangular.one('group', id).getList('items').then(function(data){
$scope.items = data;
});
Now I want that datas be available offline and refreshed time to time.
Localstorage is not possible because I ll have +5MB of datas and images.
I see a lot of posts about file API but does it mean I need to have a file for each item?
eg: item1.json, item2.json and a file for the list items.json
I think there is a better solution than having 500+ different files...
How to handle images? Do I need to parse my api, download images and replace with local links?
Why not use WebSQL? As a web standard, it is dead, but it works well on mobile and works great in PhoneGap/Cordova. As for images, I'd probably store them as binary though on the file system.

Complex JSON Structure

I am tackling frontend development (AngularJS) and rather than pull data from the backend (which isn't complete but renders everything to JSON), I am looking to just use hardcoded JSON.
However, I am new to this and can't seem to find anything about complex JSON structure. In a basic sense, my web app has users and the content they create. So, in my mind, there will be two databases, but I'm not sure if I'm approaching it correctly.
Users - username, location, created content, comments, etc.
"user": [
{
"userID": "12",
"userUserName": "My Username",
"userRealName": "My Real Name",
"mainInterests": [
{
"interest": "Guitar"
},
{
"interest": "Web Design"
},
{
"interest": "Hiking"
}
],
"userAbout": "All about me...",
"userComments": [
{
"comment": "this is a comment", "contentID" : "12"
},
{
"comment": "this is another comment", "contentID" : "123"
}
],
}
]
Created Content - title, description, username, comments, etc.
"mainItem": [
{
"mainID": "1",
"mainTitle": "Guitar Lessons",
"mainCreatorUserName": "My Username",
"mainCreatorRealName": "My Real Name",
"mainTags": [
{
"tag": "Intermediate"
},
{
"tag": "Acoustic"
},
{
"tag": "Guitar"
}
],
"mainAbout": "Learn guitar!",
"mainSeries": [
{
"videoFile": "file.mov",
"thumbnail": "url.jpg",
"time": "9:37",
"seriesNumber": "1",
"title": "Learn Scales"
},
{
"videoFile": "file.mov",
"thumbnail": "url.jpg",
"time": "8:12",
"seriesNumber": "2",
"title": "Learn Chords"
}
],
"userComments": [
{
"comment": "this is a comment", "userID" : "12"
},
{
"comment": "this is another comment", "userID" : "123"
}
]
}
]
And there is more complexity than that, but I just would like to understand if I'm approaching this right. Maybe I'm even approaching this entirely incorrectly (for instance, CRUD vs. REST? Does it matter here? As I understand it, REST implies that each of the objects above are resources with their own unique URI? So would JSON rendered be impacted?). I really am not sure. But ultimately, I need to use the JSON structure properly pull data into my frontend. Assumably, whatever said structure is will be mirrored and rendered in the backend.
Edit* thank you guys for the replies. I think part of my question, where I clarify "complex", is missing. So I'd like to explain. I guess more than the JSON itself, I really mean the structure of the data. For instance, in my example, I am structuring my data to all be beneath two unique objects (user and content). Is this correct? Or should I think about my data more diverse? For instance, technically I could have a comments database (where each comment is the main object). Or is that still implied in my dataset? Perhaps my question isn't even about JSON as much as it is the data structure which will happen to get rendered in JSON. Hopefully this clarifies what I mean by complex?
Any and all help is appreciated.
I'm not sure why you're making what seems to be objects into single-item arrays (as evidenced by the opening square brackets). Other than that, it looks fine to me. Generally speaking single items (like "User") are structured as an object and multiples are arrays of objects.
As for the Angular stuff, if you want to pull direct from a JSON file as a test, take a look here:
var services = angular.module('app.services', [])
services.factory('User', function($http) {
var User = function(data) {
return data;
}
User.findOne = function(id) {
return $http.get('/test_user.json').then(function(response) {
return new User(response.data);
});
};
return User;
});
I also recomment looking into Deployed for doing development without access to live data services.

Categories