Backbone.js 404 (Not Found) error when using .save() command - backbone.js

I'm fetching data using backbone.js with the following code. The .get and .set commands work fine, but if I set JSON data, then use .save(), I get a 404 (Not Found) error.
var ExampleModel = Backbone.Model.extend({});
var example = new ExampleModel({});
example.url = "data/example.json";
example.fetch();
I'm using a basic server with the connect.js module:
var util = require('util'),
connect = require('connect'),
port = 8080;
connect.createServer(connect.static(__dirname)).listen(port);
util.puts('Listening on ' + port + '...');
and example.json looks like so:
{
"home": "new york",
"status": "married",
"kids": "one"
}
Is the problem with my server? Any help will be greatly appreciated.Thanks!

This might sound dumb but it is similar to a problem I had a few months ago with one of my backbone applications running with rails as a web server. Try defining the model 'url' adding a backlash at the beggining like this:
var ExampleModel = Backbone.Model.extend({
url: '/data/example.json'
});
In my example I define the url attribute inside the model because I think it's cleaner but you can do differently if you like.

Related

How to make an Xhr request to get client's ip via external api

I need to get client's public ip and geolocation using some api : ipapi.co, ip-api.com, ipdata.co, etc. and grab its json result, I tried with : new qx.io.request.Xhr without luck. Can someone tell me how to get this info using any of these apis ? Thanks
Ok, after some hours digging blogs and forums, I got the info using :
var url = 'https://ipinfo.io/json';
var jsonStore = new qx.data.Store.Json(url);
jsonStore.addListener( 'loaded', function(e) {
var ipdata = e.getData();
console.log( ipdata.getIp() )
}, this);
In case someone else might need it.

Express Get api

I'm practicing right now with the MEAN stack.
I've made a project with the Angular shell and I've inclueded express in my project.
Here's my first GET, i want to use it to retrive some data from my mongoDB, in this case an entire collection:
router.get('/biscottigrazie', function(req, res) {
var db = req.db;
var collection = db.get('biscotti');
});
Maybe I'm missing the concept but i think that from angular i should be able to "call" this GET and get the data.
So, my var collection should contain the data, how can I retrive them from angular files?
You will not get db instance from request variable. You will get it while you define database.
var db = new Db('test', new Server('localhost', 27017));
router.get('/biscottigrazie', function(req, res) {
var collection = db.getCollection('biscotti');
res.send(collection);
});

How to make an angularjs application 12 factor compliant regarding configuration

I'm trying to make an angularjs app 12 factor compliant regarding config (http://12factor.net/config).
It should depend on the environment and I should not see the words development, test, production, etc. in the code.
Variables could be stored in bash env for example.
I could pass them to a webserver.
I already thought of an .erb template file to erb config.js.erb > config.js, but if I change a variable while the application is running I'd have to redo this.
I already found this article http://mindthecode.com/how-to-use-environment-variables-in-your-angular-application/
But it's a big lie and Grunt.js to do this, really... Anyway.
I know 12factor philosophy wasn't made for frontend application but my angular application could be deployed in many different servers across many environment and it won't harm anyone to try to do things properly :).
Thanks !
Edit:
The config parameters I'd like to use would be some stuff like :
app:
api:
url: "The url of the api server"
port: 8080
cdn:
images: "url of my images caching service"
google:
oauth:
"api_key": "The api key used for that deployment"
#other external frontend services
Other Edit:
This guy kinda went with an answer : http://bahmutov.calepin.co/inject-valid-constants-into-angular.html which I find kind of ugly and totally bound to angularjs; but it works !
Here is the solution I found, it's totally bound to angularjs but it works for me on Heroku and it's very simple. I just append my conf module to the generated code.
Everytime I restart the app a new version of the code is copied therefore the Append only happens once.
The Append just redefines an already existing configuration variable.
If someone find something more 'classy' I'd be happy to put it as the right solution !
var compression = require('compression');
var express = require('express');
var logfmt = require('logfmt');
var stdio = require('stdio');
var glob = require("glob");
var fs = require('fs');
// ------------------------
// Read config from args
var ops = stdio.getopt({
'url': {
key: 'u',
args: 1,
default: '',
description: 'Url of api server'
},
'port': {
key: 'p',
args: 1,
default: 5000,
description: 'Port on which to listen'
}
});
var port = ops.port || process.env.PORT;
ops.port = undefined;
// ------------------------
// Append config to js built file
var codeToAppend = 'angular.module("project.config",[]).constant("ApiConfig",' + JSON.stringify(ops) + ');';
glob(__dirname + '/dist/scripts/scripts.*.js', function(er, files) {
fs.appendFile(files[0], codeToAppend, function(err) {
if (err) {
throw err;
}
console.log('The "conf code" was appended to file!');
});
});
// ------------------------
// Start App :3
var app = express();
app.use(logfmt.requestLogger());
app.use(compression({
threshold: 512
}));
app.use(express.static(__dirname + '/dist'));
app.get('/config', function(req, res) {
res.json(ops);
});
app.listen(port);
I found a repository on github that hopefully help you Angular-Express-Train-Seed

Backbone.js DELETE request not firing

I'm trying to get the backbone.js DELETE request to fire, but don't see any requests being made in my console.
I have collection model like so:
var Model = Backbone.Model.extend(
{
urlRoot: '/test',
defaults:{}
});
var TableList = Backbone.Collection.extend(
{
url: '/test',
model: Model
});
In my view I'm running this:
this.model.destroy();
Everything seems to be running fine, I can see output coming from the remove function that calls the destroy so I know it's getting there plus it also successfully runs an unrender method that I have. Can't see any requests being made to the sever though?
If I am not mistaken, you have to have an id property on your model to ensure that it hits the correct url. IE if your model was...
var Model = Backbone.Model.extend({
url: '/some/url'
});
var model = new Model({
id: 1
});
model.destroy(); // I THINK it will now try and DELETE to /some/url/1
Without an id it doesn't know how to build the url correctly, typically you'd fetch the model, or create a new one and save it, then you'd have a Url...
See if that helps!
I found the issue to my problem, thought not a solution yet. I'm not sure this is a bug with backbone or not, but I'm using ajaxSetup and ajaxPrefilter. I tried commenting it out and it worked. I narrowed it down to the ajaxSetup method and the specifically the use of the data parameter to preset some values.
Have you tried using success and error callbacks?
this.model.destroy({
success : _.bind(function(model, response) {
...some code
}, this),
error : _.bind(function(model, response) {
...some code
}, this);
});
Might be instructive if you're not seeing a DELETE request.

Backbone collection/model best practice

In my application we are using RequireJs and Backbone
So a typical model might look like the following in a separate file so we can attempt to modularize this application better:
define([
'Require statements here if needed'
],
function() {
var toDo = Backbone.Model.extend({
// Model Service Url
url: function () {
var base = 'apps/dashboard/todo';
return (this.isNew()) ? base : base + "/" + this.id;
},
// Other functions here
});
return toDo;
});
Right now we keep each model and collection in its own file and return the Model/Collection as above. The bigger the application gets the harder it is to keep the files and naming convention straight. I would like to combine similar collections/models together into 1 file and maintain the modularity.
What is a good way to achieve this? Or should I stick with them in separate files and get a better naming convention? If so, what do you use for your naming convention between similar Collections/Models?
This is the way I structure my application :
I have a javascript path, which I'm minifying on demand by the server when client access "/javascript", so I have only one script line in my index.html :
<script src='/javascript'></script>
My directory structure of /javascript is the following :
application.js
router.js
lib/
lib/jquery.js
lib/underscore.js
lib/backbone.js
lib/require.js
lib/other_libraries.js
views/
views/navigation.js
views/overlay.js
views/content.js
views/page
views/page/constructor.js
views/page/elements
views/page/elements/constructor.js
views/page/elements/table.js
views/page/elements/form.js
views/page/elements/actions.js
collections/
collections/paginated.js
All those files are minified and loaded from client in the first request. By doing this I have a lot of my code already loaded in my browser before the application makes any requests with RequireJS.
On my server I have a directory, which is also public, but is for dynamic javascript loading and templates ( it is accessed by demand from the application at any given time ). The directory looks like this :
dynamic/
dynamic/javascript
dynamic/javascript/pages
dynamic/javascript/pages/articles.js
dynamic/templates
dynamic/templates/pages
dynamic/templates/pages/articles.hb
dynamic/templates/pages/items.hb
When my server requests "/templates/pages/articles.hb" the server returns JSON object which looks like this :
{ html : "<div class='page' id='articles'>blah blah blah</div>", javascript : "javascript/pages/articles.js" }
And when my client app receives "javascript" property in the returned JSON object it triggers a RequireJS request
if ( typeof json.javascript === string ) {
require([ json.javascript ], function(constructor) {
window.app.page = new constructor();
});
}
In the dynamic/javascript/pages/articles.js I have something like :
define(function() {
var Model = Backbone.Model.extend({});
// Collections.Paginated is in fact the Collection defined by /javascript/collection/paginated.js
// it is already loaded via the initial javascript loading
var Collection = Collections.Paginated.extend({
url : '/api/articles'
});
// Views.Page is in fact the View defined by /javascript/views/page/constructor.js
// it is also already loaded via the initial javascript loading
var articles = Views.Page.extend({
collection : Collection,
initialize: function(options) {
this.collection = new Collection();
});
});
return articles;
});
Pretty much that's it. I have minimum requests with RequireJS, because every time you hit require('something.js') it makes a request to the server, which is not good for your application speed.
So the exact answer of your question ( in my opinion ) is : You should make your initial loaded files separated as much as possible, but later loaded files with requireJS should be as small as possible to save traffic.

Resources