Get same Item collection but with different limits - javascript

In my Backbone project, I am getting a collection of Items through the following Model:
MyApp.models.Items = Backbone.Model.extend({
url: "getItems"
});
and then later:
var model = new MyApp.models.Items();
model.fetch().then(function(data){
// do something here with fetched data
});
This Implementation works fine but I have a situation where I am getting all the Items on Home page and only 3 items in other page.
I feel it will be overkill if I fetch all the Items and then using the above model to limit it to 3 Items.
How can I use the same model to get a limited number of items or all items?
PS: I am new to Backbone.

The Backbone collection (Doc : http://backbonejs.org/#Collection) is a set of models.
Its best to use a backbone collection when you are dealing with data that is used to populate UI components like data gird / table, data lists e.t.c were you need a set of data.
MyApp.collections.ItemCollection = Backbone.Collection.extend({
model: Item,
url: "getItems"
});
The model attribute inside the collection specifies the type of data the is present in the collection. The collection uses this information to efficiently manage data inside it (merge during server fetch for already existing models /can pass raw json data to methods like add).
Using the collection fetch method(http://backbonejs.org/#Collection-fetch), data is fetched from the server.
var itemCollection = new MyApp.collections.ItemCollection();
itemCollection.fetch({
// The data property is used to send input data to the server method.
// Any data that will be required by the server method can be passed using this.
data: {
limit : 5
},
success : function(collection, response, options) {
//Do your logic
console.log("Success...");
}
error: function(collection, response, options) {
//Do your logic
}
});

In your scenario, you say you fetch all the items in homepage and only use part of it in other page.
For me, I would use router.
When the user moves from homepage to other page, you don't need to fetch new items, just choose the needed items (3 items) and render it.

Related

Create table dynamically using Sequelize

I wanted to ask you if it is even possible to create tables dynamically in NodeJS using Sequelize.js. My goal is to create a simple TODO list where users can create a list (this list should be one table in my database). I have successfully established a connection with my database, created some simple models for my users. I want them to add tasks to their lists. I have also created a POST request route in NodeJS where the creation of the table should be done.
I found a code that can create a table (which it does) but I cannot add any items inside the list because the variable is local and I cannot use it anywhere in the code except the POST request in NodeJS. It still feels like static to me..
app.post('/todo/create', async(req: Request, res: Response): Promise <void> => {
....
let Dummy = sequelize.define('dummy', {
description: Sequelize.STRING
});
....
}
For example, if I want to use it like I use my user model down below in login POST request
const existsUser = await User.findOne({where: {username: user}});
Any help or good direction would be much appreciated.

App Maker delete items on table and update

I have an app that I would like to be able to take columns from a google spreadsheet and make a list on a table in my app. Also I would like to be able to remove items from this table.
As of now I am using the AMU library function AMU.deleteAll, all it does is
AMU.deleteAll = function(widget){
var records = widget.datasource.items;
records.forEach(function(record){
record._delete();
});
};
So what happens is that when I have a completely new and blank table my app can update from my spreadsheet when I use AMU.import.fromSpreadsheet (check here for full library goo.gl/RkeqZw) it will take all the items from my spreadsheet and place them properly in my table, after that I can use the delete function to remove all items on my table. Here is where things get all screwy, when I try to use the import function again the list gets populated with empty entries and if I try to use the delete function I get an error:
"Drive Table internal error. Record not found. Caused by: Execution Failed. More information: Object not found at path: camo0A_084fQ. (HTTP status code: 404) Error: Drive Table internal error. Record not found. at deleteAllData (ServerScript:232)"
I am not sure why this is happening, to me it seems like the data is being saved and the delete function only removes the value, and not the actual entry.
If you want to delete all items from your model you can make single server call (the code you quoted above does sever call for each individual item loaded on client):
// server script to delete all records from model
function deleteAllRecordsFromModel() {
var allRecords = app.models.MyModel.newQuery().run();
app.deleteRecords(allRecords);
}
// client script to call server function
google.script.run
.withSuccessHandler(function() {
// TODO: Handle success (optional)
})
.withFailureHandler(function() {
// TODO: Handle error (optional)
})
.deleteAllRecordsFromModel();

Multiple Backbone.js collection options?

Intro:
Building in node.js and express on the backend, I am sending a res.json(details) to the localhost:3000/me route containing the users session information.
So that on the client side I can work with that specific user, for example on the client side initialization I write some code like this.
var me = new MeModel();
me.fetch({
success: function(response) {
App.data.me = me;
var messages = new MessagesCollection([], { id: response.get('user_id') });
messages.fetch({
success: function() {
App.data.messages = messages;
App.core.vent.trigger('app:start');
}
});
}
});
You see I fetch the me model and use that to filter the messages in the MessagesCollection.
Question:
In my MessagesCollection I pass options like this.
module.exports = MessagesCollection = Backbone.Collection.extend({
initialize: function(models, options) {
this.id = options.id;
},
url: function() {
return '/api/messages/' + this.id;
},
model: MessageModel,
//url: '/api/messages'
});
This is great for getting the desired models when using var messages = new MessagesCollection([], { id: response.get('user_id') });
My question is when somewhere else I run window.App.data.messages.create(Message); this wants to POST to /api/messages/:id when I want to POST to the regular collection?
Theory:
So obviously I would say the best thing is to rethink how I filter the models in the fetch method.
So basically to simplify this question I need to filter the collection upon .fetch() GET... and set no filters upon .create() POST
BTW I am using marionette, maybe that can help with something?
model.url() Returns the relative URL where the model's resource
would be located on the server. If your models are located somewhere
else, override this method with the correct logic. Generates URLs of
the form: "[collection.url]/[id]" by default, but you may override by
specifying an explicit urlRoot if the model's collection shouldn't be
taken into account.
Delegates to Collection#url to generate the URL, so make sure that you
have it defined, or a urlRoot property, if all models of this class
share a common root URL. A model with an id of 101, stored in a
Backbone.Collection with a url of "/documents/7/notes", would have
this URL: "/documents/7/notes/101"
http://backbonejs.org/#Model-url
So you can define method url at MeModel and generate url there ( if there are no other users - you can just return string "/me" or generate in based on model properties ( for example switch if model has id )

Javascript Backbone model design

Fairly new to JavaScript so it might be a noobish question.
At the moment for my project I'm using NodeJS for my server and Backbone for the client. The client will send a request to the server and the server will send list of files in the server, my aim was to simply return the list of files and when user click on the file it will send another request to the server to load the file.
Currently in the client level my model and collection is defined something like:
app.MyFile = Backbone.Model.extend({
defaults: {
modifiedDate: new Date(),
path: '',
content: '' // content of the file
}
});
var MyFileList = Backbone.Collection.extend({
model: app.MyFile,
url: '/api/files'
});
// create global collection of files
app.MyFiles = new MyFileList();
app.AppView = Backbone.View.extend({
initialize: function () {
// fetch all files
app.MyFileList.fetch();
}
});
// app.js (point of entry)
$(function() {
// Kick things off by creating the **App**.
new app.AppView();
});
And my server code:
var application_root = __dirname,
express = require("express"),
...
app.get('/api/files', function(req, res) {
...
// return file list
}
app.get('/api/files/:id', function(req, res) {
...
// return file content?
}
Since it doesn't make sense to load all files in the directory and send it back to the client, what I did was I created the model in the server and fill up modifiedDate and path while leaving content to null. But the problem now is that how do I fill up the content when user clicks on the file? I'm not sure how to manually send an HTTP request from Backbone View or controller. Or is there any better way of doing this? One way that I can think of is to create another model that only keeps modifiedDate and path but to me this looks very verbose and repetitive.
Given what you have on the client side, you may not need anything more.
app.MyFiles = new MyFileList();
app.MyFiles.fetch().done(function() {
// your collection is fetched but each model's content is empty.
// now, I assume at this point you will show them in some view/views.
});
Now when one of those things is clicked on, you can fetch the content.
var model = app.MyFiles.get(id);
model.fetch().done(function() {
// now the model's content attribute will be set
});
This might work with no more code than what you showed. Because the url a model uses to fetch is created by default by appending the model's id to the end of its collection's url.
So from your server, you return a json array from '/api/files': [{id:1, path:'foo'}, {id:2, path:'bar'}]
Then from '/api/files/1': {id:1, path:'foo', content:'whatever'}
When user clicks the file, you can call backbone's fetch method on the model. Then your model will be filled with data from the server.
Note that for this to be working you should return collection from the server first, where models at least have id's. Every other field will be filled after fetch call. Also, you should override model url, if it differs from standard (which is collection/id).

What should I use to filter backbonejs Collection on server?

I want to filter my backbone Collection on server side?
Current I pass query params via data:
Books.fetch({data: {published: true, page: 3}})
Is there any better way to do this?
Books.filter(function (book) {
return filterCondition(book);
}).fetch();
Filter your collection to the books you want, then invoke fetch on the new collection.

Categories