What is the best practice when displaying data from more than one table - javascript

I have three tables, 'sessions', 'classes' and 'schedules' which they are connected each other.
sessions: id, name, descr
classes: id, session_id, name
schedules: class_id, session_id, date
A class belongs to a session, while the schedules is a N:M relations which gives the opportunity to have particular date for each session within a single class.
My problem comes when I have to display these information, I have a function which displays all Sessions:
$sessions = Session::all();
and I have another function which displays the date of a specific class and a specific session as below:
$result = Schedule:where('class_id','=',$classId)->where('session_id','=',$essionId)->first();
So let say I have 30 sessions for a single class, when it comes to my front-end app which is written in AngularJS I dont know how to handle the displaying here using the ng-repeat iterating thru all sessions and then make another call withing the ng-repeat iteration to call the schedule to display the date of the session, this is not a good practice I guess in AngularJS.
Could anyone tell me what would be the best option for me to handle this problem? Shall I have to modify the back-end? like edit the Session:all(); query to include also the Schedule table? or what is the best way?

I supposed you have already config your relations in models, if not look here
As for me, I use Fractal to customize display data. Also there is convenient method called Available includes
So you can request your data like /sessions/?include=classes and get output
{data: [{
session_id: 1,
some: "data",
classes:[{
class_id: 11,
some: "class_data"
}]
}]}

I would "eager load" the data, so you can access all the object's parents through the object you loaded. This way you can fill your table rows one by one by just iterating over 1 object.
There is excellent documentation about eager loading at the Laravel website, so I suggest you start there

Related

How can I retrieve data from a foreignID

I am new to laravel and I am struggling to retrieve data using the query Builder.
Consider the following migration on the Hotel table:
$table->id();
$table->timestamps();
$table->foreignIdFor(User::class);
$table->foreignIdFor(Room::class);
Now consider that I have in my HotelController:
$hotel = Auth::user()->hotels which retrieves this on dd:
[{"id":1, "user_id":51,"room_id":11, "booking_id":7}
[{"id":2, "user_id":51,"room_id":16, "booking_id":21}
[{"id":3, "user_id":51,"room_id":18, "booking_id":44}
[{"id":4, "user_id":51,"room_id":45, "booking_id":33}
I now want to retrieve the data from each of the room_id and booking_id from each of the Auth users which in this case is user 51. Can anyone help me with how can I achieve this?
Thank you in advance
Assuming you defined the relationships (belongsTo, hasOne, hasMany, etc) in the models for Hotel, Room and Booking, you can just iterate through the list of hotels getting each hotel into a $hotel local variable, and asking for their related models information like this:
foreach ($hotels as $hotel) {
$hotel->room // gets you the related room
$hotel->booking // gets you the related booking
}

I'm getting a "newItem() was not passed an identity for the new item" error while trying to add a new item to a JSON store

I've seen other posts in this site regarding the same issue and I've tried the solutions given. I've also visited the links that may offer a solution but I'm still stuck with the same error.
I'm using DOJO and something as simple as this won't even work
myStore.newItem({id: 'test', otherfield: 'otherinfohere'});
myStore.save();
Supposedly the "newItem() was not passed an identity for the new item" error appears when you haven't provided an identifier for the new item, which i have.
The whole purpose of this (Just in case anyone can provide a good idea or has done something similar before) is that i want to create a data grid that shows info from a particular store. The problem is, that in that store all the items may not have the same structure. For instance:
I may have a store that looks like this
{identifier: 'id',
label: 'name',
items: [
{ id:'1', name:'Ecuador', capital:'Quito' },
{ id:'2', name:'Egypt', capital:'Cairo' },
{ id:'3', name:'El Salvador', capital:'San Salvador' , additionalField: 'otherinfohere'},
{ abbr:'gq', name:'Equatorial Guinea', capital:'Malabo', additionalField: 'otherinfohere'},
]}
This is possible because I'm the one constructing the store in a Spring Controller (I'm also using the Spring Framework) from information I have locally stored in a Berkeley DB. So what i need is a data grid with a dynamic layout because I don't want blank spaces to show in the view in the rows with lesser amount of fields, and i need to show all the info in the store at the same time, but i don't know how to do this.
I thought of doing it by creating a simple layout of only 1 field. In it I would load data from a store i create dynamically at runtime. The data in the store would be composed of HTML combined with the values coming from the original store so I could obtain something like this, which is inside an attribute of a JavaScript Object and let the browser parse it for me:
<div><span>id: originalID </span>....</div>
This of course is a simple example, the html layout i'm looking for is far more complicated, but i think that passing it as a string to an object might do the trick.
The problem is that i don't even know if that idea will work because i get that error whenever i try to add values to my secondary store.
rdb.modules.monitor.historicStore.fetch({onComplete: function(items, request){
for (var i = 0; i < items.length; i++){
var item = items[i];
var obj = new Object();
obj.id = rdb.modules.monitor.historicStore.getValue(item, "id");;
var html = "<div><span>";
html += rdb.modules.monitor.historicStore.getValue(item, "sql");
html += "</span></div>";
obj.html = html;
myStore.store.newItem(obj);
}
}});
In this context "historicStore" refers to the JSON store that has the values that i need to convert and add to "myStore" after i added some HTML.
I hope you got the main idea of what I'm trying to do. If anyone can help me we either of these problems i would really appreciate it. Thanks in advance
For the issue regarding store:-
"id" is mandatory for a store, if it is going to be used for a grid(datagrid, EnhancedGrid, etc. whatever). The items are handled only on basis of "id" attribute by the grid data structures.
Usually, id can be a loop variable/ auto incrementation, to avoid any cases like you have said. Before adding the store to the grid, ensure that all items have the id attribute. You can write a function which will loop through each item and check for this, else add an auto-incrementing value for the id attribute of that item.

Angular.js accessing and displaying nested models efficiently

I'm building a site at the moment where there are many relational links between data. As an example, users can make bookings, which will have booker and bookee, along with an array of messages which can be attached to a booking.
An example json would be...
booking = {
id: 1,
location: 'POST CDE',
desc: "Awesome stackoverflow description."
booker: {
id: 1, fname: 'Lawrence', lname: 'Jones',
},
bookee: {
id: 2, fname: 'Stack', lname: 'Overflow',
},
messages: [
{ id: 1, mssg: 'For illustration only' }
]
}
Now my question is, how would you model this data in your angular app? And, while very much related, how would you pull it from the server?
As I can see it I have a few options.
Pull everything from the server at once
Here I would rely on the server to serialize the nested data and just use the given json object. Downsides are that I don't know what users will be involved when requesting a booking or similar object, so I can't cache them and I'll therefore be pulling a large chunk of data every time I request.
Pull the booking with booker/bookee as user ids
For this I would use promises for my data models, and have the server return an object such as...
booking = {
id: 1,
location: 'POST CDE',
desc: "Awesome stackoverflow description."
booker: 1, bookee: 2,
messages: [1]
}
Which I would then pass to a Booking constructor, which would resolve the relevant (booker,bookee and message) ids into data objects via their respective factories.
The disadvantages here are that many ajax requests are used for a single booking request, though it gives me the ability to cache user/message information.
In summary, is it better practise to rely on a single ajax request to collect all the nested information at once, or rely on various requests to 'flesh out' the initial response after the fact.
I'm using Rails 4 if that helps (maybe Rails would be more suited to a single request?)
I'm going to use a system where I can hopefully have the best of both worlds, by creating a base class for all my resources that will be given a custom resolve function, that will know what fields in that particular class may require resolving. A sample resource function would look like this...
class Booking
# other methods...
resolve: ->
booking = this
User
.query(booking.booker, booking.bookee)
.then (users) ->
[booking.booker, booking.bookee] = users
Where it will pass the value of the booker and bookee fields to the User factory, which will have a constructor like so...
class User
# other methods
constructor: (data) ->
user = this
if not isNaN(id = parseInt data, 10)
User.get(data).then (data) ->
angular.extend user, data
else angular.extend this, data
If I have passed the User constructor a value that cannot be parsed into a number (so this will happily take string ids as well as numerical) then it will use the User factorys get function to retrieve the data from the server (or through a caching system, implementation is obviously inside the get function itself). If however the value is detected to be non-NaN, then I'll assume that the User has already been serialized and just extend this with the value.
So it's invisible in how it caches and is independent of how the server returns the nested objects. Allows for modular ajax requests and avoids having to redownload unnecessary data via its caching system.
Once everything is up and running I'll write some tests to see whether the application would be better served with larger, chunked ajax requests or smaller modular ones like above. Either way this lets you pass all model data through your angular factories, so you can rely on every record having inherited any prototype methods you may want to use.

Backbone-relational: Association key won't work unless it's the same as the foreign key

I'm trying to get the backbone-relational plugin working with an association between tasks and messages. (A task has many messages).
The information is pulled from a standard rails/activerecord site, which has a task_id field as the foreign key.
The problem is, backbone-relational won't populate the 'messages' field with any messages on teh Task model unless I set the key as "task_id" in the reverse relation...but that means that, when accessing the task from the Message model, the task_id field is populated with the actual task object, not the 'task_id' integer, which is overwritten.
I'm guessing there's a simple way to specify task_id as the foreign key with which to determine the parent task, yet have the object that key represents placed in a different field (eg 'task' on the messages object)...but I can't figure out how. Any ideas appreciated. Code below
class Backbonescaffolddemo.Models.Task extends Backbone.RelationalModel
paramRoot: 'task'
relations: [{
type: Backbone.HasMany,
key: "messages",
relatedModel: "Backbonescaffolddemo.Models.Message",
collectionType: "Backbonescaffolddemo.Collections.MessagesCollection",
includeInJSON: true
reverseRelation: {
key: "task_id"
includeInJSON: true
}
}]
You may be able to use keySource or keyDestination to address your particular problem.
Example
In the following example, suppose we are getting data from an old-school relational database, where there is a one-to-many relationship between Monster and Loot_Item. This relationship is expressed by a Monster_Id foreign key in the Loot_Item table. Let us also suppose that our REST service doesn't do any fancy-pants data nesting for us, since that seems to match the situation in your question fairly closely.
keySource
Now, let's set set "keySource" to my foreign key ("Monster_Id") and "key" to the name of the attribute where I want the actual data to go (say, "Monster"). If you break in the debugger, you will see in the attributes object that there is, in fact, a field called "Monster", and that it does point to the monster model data. Hey, cool!
includeInJSON
However, if you toJSON that puppy, guess what? It has put all the monster data in Monster_Id, just like you didn't want! GAH! We can fix that by setting "includeInJSON" to "Monster_Id". Now, when it is converted to JSON, it puts the proper ID back into the Monster_Id field, when it is serializing your data to JSON, to send up to the server.
Problem solved? Er, well, actually, not necessarily...
CAVEAT: This all sounds super-useful, but there's one fairly glaring problem that I have found with this scenario. If you are using a templating engine (such as the one in Underscore.js) that requires you to convert your model to JSON, before passing it into the template, whoops -- you don't have access to your relational data. Alas, the JSON that we want for our messages is not necessarily the same JSON that we want to feed into our templates.
If you want the "task_id" in the message JSON to be the id, not the full JSON for the task, then set the "includeInJSON" to be the Task's ID property ("task_id")
class Backbonescaffolddemo.Models.Task extends Backbone.RelationalModel
paramRoot: 'task'
relations: [{
type: Backbone.HasMany,
key: "messages",
relatedModel: "Backbonescaffolddemo.Models.Message",
collectionType: "Backbonescaffolddemo.Collections.MessagesCollection",
includeInJSON: true
reverseRelation: {
key: "task_id"
includeInJSON: "task_id"
}
}]
The "true" value for includeInJSON says to use the full JSON for the related model.
Edit: After re-reading your question, I'm not sure my answer relates to your issue.
My original answer is for posting a message back to the server where you want the JSON to be something like:
{
"message_title": "My Title",
"message_body": "Blah blah blah...",
"task_id": 12345
}
I'm not sure what exactly you're looking to happen, but the way that Backbone Relational is supposed to work is that the Task's collection of messages will be a collection of the full models, so you can iterate over them and pass them to views for rendering, etc.
If you want to output one of the Message's id's in a template or something, then you'd take the Message model's "id":
myTask.get('messages').first().id -> returns the first message's id

Get full data set, sorted with YUI Data Table with Pagination

I hope I am describing my issue enough.. here goes:
I have a YUI data table, get a server side set of records via JSON, and then populates the data.
Users can click on the headers to sort the data in three of the 6 columns, (which are using a custom sort function for each column). The sorting is done client-side.
When a user sorts the data, I need to be able to get a complete list of the values from one of the columns being shown. I need all the data available, not just what's rendered to the page. The data hidden via pagination must be included.
Any ideas? I've tried the handleDataReturnPayload and doBeforeLoadData methods of the DataTable but both give the original, unsorted data.
I'm really stuck here and I've got a client depending on a feature that depends on me getting this sorted list.
Thanks in advance.
Satyam, over at the YUI Forums answered my question perfectly.
The data is actually stored in the
RecordSet. At any time you can go and
look at it, and it will be sorted as
shown on the screen, but it will have
all the data, whether shown or not.
Method getRecordset() will give you a
reference to it and then you can loop
through its records.
You can listen to the columnSortEvent
to be notified a sort has occurred.
I just subscribed to the columnSortEvent event and looped through the array returned by datatable.getRecordSet().getRecords().
I'd recommend posting this to the YUI forums -- http://yuilibrary.com/forum/ -- that's a great place to get support on DataTable issues.
I stumbled upon this question looking for information on how to retrieve information from a dataset that was NOT displayed in the datatable. IF you place the hidden data in the datasource before any field you wish to be displayed, it will be rendered blank, but if you place it after your last field that will be rendered (as defined by the columns object), then they will not render but still be accessible through the record).
var columns = [
{key:"Whatchamacallits", children:[
{key:"name" },
{key:"price" }
]}
];
var ds = new YAHOO.util.DataSource('index.php...');
oDataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
oDataSource.responseSchema = {
fields:["name","price","id"]
};
var dt = new YAHOO.widget.DataTable("dt-id", columns, ds, {});
dt.subscribe("rowClickEvent", dt.onEventSelectRow);
dt.subscribe("rowSelectEvent", function(p){ alert(p.getData('id'); });

Categories

Resources