Using web2py, jQuery and ajax, how do you post to a database? - ajax

Using web2py I am trying to use ajax to put data into a table in my database, but I'm needing a bit of help.
Here is the function I am using (it currently has dummy data in the data section, rather than being passed data from a form):
function submitData(){
$.ajax({
type: "POST",
url: "requests",
data: {
id: 1,
user_id:111,
bottle_image:'',
bottle_name:'JJjman',
bottle_description:'Lol',
request_creationDate:'2000-01-01',
request_expiryDate:'2003-08-08',
request_fulfilled:false
},
success: function(){
alert('Posted data');
}
});
}
I have a html button with this function attached to its 'onclick', but at the moment all it does is reload the page and not pass any data onto the database. The success alert is also coming up.
Firebug is saying that the POST does contain all that data, but I'm not sure if the POST is actually going anywhere..
Am I missing any steps needed to actually pass this data to the database? Or could this just be that my data isn't all the right type for the database?
Cheers guys

Simply sending a post from the browser won't do anything on the server unless you have code on the server to handle the data and insert it into the database.
I strongly recommend you read through the relevant parts of the book to learn how to do this. The Overview chapter provides an introductory tutorial, including building an image blog that involves modeling a database table and creating a form to post records to that table.
Review the DAL chapter for details on modeling your database, the section on SQLFORM for details on creating forms associated with database tables, and the sections on ajax and components for details on using Ajax to post forms.
The easiest way to do what you want would be something like this:
In /models/db.py:
db = DAL('sqlite://storage.sqlite')
db.define_table('bottle',
Field('user_id')
Field('bottle_image'),
Field('bottle_name'),
Field('bottle_description', 'text'),
Field('request_creationDate', 'date'),
Field('request_expiryDate', 'date'),
Field('request_fulfilled', 'boolean'),
format='%(bottle_name)s')
In /controllers/default.py:
def index():
return dict()
def add_bottle():
return dict(form=SQLFORM(db.bottle).process())
In /views/default/add_bottle.load:
{{=form}}
In /views/default/index.html:
{{extend 'layout.html'}}
{{=LOAD('default', 'add_bottle.load', ajax=True)}}
Then go to /yourapp/default/index, and you will see a form, which will post records to the database via Ajax.

Related

How to use NodeJS with node-rest-client methods to post dynamic data to front end HTML

I am rather new to NodeJS so hopefully I am able to articulate my question(s) properly. My goal is to create a NodeJS application that will use the node-rest-client to GET data and asynchronously display it in HTML on client side.
I have several node-rest-client methods created and currently I am calling my GET data operation when a user navigates to the /getdata page. The response is successfully logged to the console but I'm stumbling on the best method to dynamically populate this data in an HTML table on the /getdata page itself. I'd like to follow Node best practices, ensure durability under high user load and ultimately make sure I'm not coding a piece of junk.
How can I bind data returned from my Express routes to the HTML front end?
Should I use separate "router.get" routes for each node-rest-method?
How can I bind a GET request to a button and have it GET new data when clicked?
Should I consider using socket.io, angularjs and ajax to pipe data from the server side to client side?
-Thank you for reading.
This is an example of the route that is currently rendering the getdata page as well as calling my getDomains node-rest-client method. The page is rendering correct and the data returned by getDomains is successfully printed to the console, however I'm having trouble getting the data piped to the /getdata page.
router.get('/getdata', function(req, res) {
res.render('getdata', {title: 'This is the get data page'});
console.log("Rendering:: Starting post requirement");
args = {
headers:{"Cookie":req.session.qcsession,"Accept":"application/xml"},
};
qcclient.methods.getDomains(args, function(data, response){
var theProjectsSTRING = JSON.stringify(data);
var theProjectsJSON = JSON.parse(theProjectsSTRING);
console.log('Processing JSON.Stringify on DATA');
console.log(theProjectsSTRING);
console.log('Processing JSON.Parse on theProjectsSTRING');
console.log('');
console.log('Parsing the array ' + theProjectsJSON.Domains.Domain[0].$.Name );
});
});
I've started to experiment with creating several routes for my different node-rest-client methods that will use res.send to return the data and the perhaps I could bind an AJAX call or use angularjs to parse the data and display it to the user.
router.get('/domaindata', function(req, res){
var theProjectsSTRING;
var theProjectsJSON;
args = {
headers:{"Cookie": req.session.qcsession,"Accept":"application/xml"},
};
qcclient.methods.getDomains(args, function(data, response){
//console.log(data);
theProjectsSTRING = JSON.stringify(data);
theProjectsJSON = JSON.parse(theProjectsSTRING);
console.log('Processing JSON.Stringify on DATA');
console.log(theProjectsSTRING);
console.log('Processing JSON.Parse on theProjectsSTRING');
console.log('');
console.log('Parsing the array ' + theProjectsJSON.Domains.Domain[0].$.Name );
res.send(theProjectsSTRING);
});
});
I looked into your code. You are using res.render(..) and res.send(..). First of all you should understand the basic request-response cycle. Request object gives us the values passed from routes, and response will return values back after doing some kind of processing on request values. More particularly in express you will be using req.params and req.body if values are passed through the body of html.
So all response related statements(res.send(..),res.json(..), res.jsonp(..), res.render(..)) should be at the end of your function(req,res){...} where you have no other processing left to be done, otherwise you will get errors.
As per the modern web application development practices in javascript, frameworks such as Ruby on Rails, ExpressJS, Django, Play etc they all work as REST engine and front end routing logic is written in javascript. If you are using AngularJS then ngRoute and open source ui-router makes work really easy. If you look closely into some of the popular MEAN seed projects such as mean.io, mean.js even they use the ExpressJS as REST engine and AngularJS does the rest of heavyweight job in front end.
Very often you will be sending JSON data from backend so for that you can use res.json(..). To consume the data from your endpoints you can use angularjs ngResource service.
Let's take a simplest case, you have a GET /domaindata end point :
router.get('/domaindata',function(req,res){
..
..
res.json({somekey:'somevalue'});
});
In the front end you can access this using angularJS ngResource service :
var MyResource = $resource('/domaindata');
MyResource.query(function(results){
$scope.myValue = results;
//myValue variable is now bonded to the view.
});
I would suggest you to have a look into the ui-router for ui front end routing.
If you are looking for sample implementation then you can look into this project which i wrote sometime back, it can also give you an overview of implementing login, session management using JSON Web Token.
There are lot of things to understand, let me know if you need help in anything.

Ember Authentication paradigm

Let's consider a trivial use case: User edits his profile + we have a RESTful server. This means we have to
send a token to the server and at the same time the new information about the editing. First, the server has to decode the token, and later to CRUD the DB. We want also to send back to the client a new json model about the new user profile.
BUT the token is really a huge one, so we must send it with a POST request. We can send the additional information as a query string at the same HTTP Post. Ember Data doesn't give us the ability to decide on sending a POST request. So we have to write a manual Ember.$.ajax. But how would we retrieve the new user model to Ember? We want to take advantage of Ember Data ORM's relationships and not reinventing the wheel.
Just for the record, the manual valid post request on the EditController is (after enabling CORS on the server)+(fBSignedRequest=> the token in my case):
Ember.$.ajax('http://myapi.com/api/usrEdit?Name='+myNewName, {
type: 'POST',
dataType: "json",
data: {fBSignedRequest: this.get("FBSignedRequest")},
success: function(data, response) {
console.log(data, response);
App.newUserProfile = data; //want it to become a part of the ED ORM
},
error: function (xhr) {
console.log('error')
}
});
This is really a trivial task to ask. Why couldn't I found any answer for over a month for this? How would you do the combination of a manual ajax and a build in Ember Data ORM?
If you have another idea about this whole authentication, I will be glad to hear.
Thank you a lot!
You could simply push the model you retrieve via your request into the store. See http://emberjs.com/guides/models/pushing-records-into-the-store/

Loading external data into Ember template using ember-data/DataStore

Here is what I'm tyrnig to do:
Make ajax request to retrieve JSON data from a PHP script
Insert that information into DataStore Models
Store those models within a controller
Display the information using {{#each}} with a handlebars template
Does ember-data have a built in way of retrieving data? If not, where
should the AJAX request be implemented?
What is the best way to insert the JSON data into the DS model?
What is the best way to then sync the models up with a Controller?
Any examples that implement all of the 4 steps would also be very helpful, since I can't seem to find any.
<edit>
Like I said in the comments, this questions asks a lot at once, so to follow up, here's a work in progress fiddle: http://jsfiddle.net/schawaska/dWcUp/
This is not 100%, but covers some of your questions. It uses the FixtureAdapter.
I'll be updating it as I find time.
</edit>
1 Make ajax request to retrieve JSON data from a PHP script
Ember-Data will take care of that for you. Consider the following:
window.App = Em.Application.create();
App.Store = DS.Store.extend({
revision: 12,
adapter: 'DS.RESTAdapter'
});
App.Product = DS.Model.extend({
name: DS.attr('string'),
imageUrl: DS.attr('string')
})
The code above defines a data store (almost like an ORM) within your client app. Ember uses convention over configuration (heavily), so as per configuration this code expects your backend to have a resource in the same domain as /products which talks to GET, POST, PUT and DELETE.
2 Insert that information into DataStore Models
Considering what I said above, by calling one of the following:
App.store.find(App.Product) or App.Product.find()
EmberData will fire a GET request through AJAX targeting your resource /products, and if you say App.Product.find(1), it will target /products/1.
Your app store will use its adapter and the adapter's serializer to translate the JSON result and materialize its data into your App.Product model.
3 Store those models within a controller
This is done when defining your application router. Regardless of what you do, Ember will run its own workflow, but it provides you several hooks, giving you the control of that specific action. Consider the following:
App.Router.map(function() {
this.resource('products');
});
App.ProductsRoute = Ember.Route.extend({
model: function() {
return App.Product.find();
}
});
The code above populates the model used in the products route (which you would access at http://yourdomain.com/#/products). Internally it will generate the code for your ProductsController, or you can define your own, which should extend ArrayController.
Controllers will have a content property which is an alias to the model or model collection. Again, convention over configuration.
4 Display the information using {{#each}} with a handlebars template
Providing you're following the conventions, in your handlebars template, you should iterate through your collection like this:
{{#each product in controller}}
{{#linkTo 'product' product}}
{{product.name}}
{{/linkTo}}
{{/each}}
Does ember-data have a built in way of retrieving data? If not, where
should the AJAX request be implemented?
Yes, simply call App.Product.find() for a product model and it return you a blank ModelArray while firing the AJAX request to the products resource in your backend, then materialize/populate your data into each model once it receives the data back from the server.
What is the best way to insert the JSON data into the DS model?
You shouldn't be concerned about this if you're using ember-data. The framework does that for you in most cases. That's why we love it. You might, however, have to configure mapping, namespace and plurals depending on your backend.
What is the best way to then sync the models up with a Controller?
Something similar to this:
var product = App.Product.createRecord({
name: 'laptop',
imageUrl: 'path/to/image.png'
});
product.save();
This should fire a POST or PUT request to your backend API.
You should definitely check:
http://emberjs.com/guides/
https://peepcode.com/products/emberjs
http://toranbillups.com/blog/archive/2013/01/03/Intro-to-ember-js-and-the-new-router-api/
Making the AJAX request
// Find all pets.
var pets = App.Pet.find();
// Find pet with ID of 1.
var pet = App.Pet.find(1);
Into DataStore Models
pets above will be a DS.RecordArray containing many App.Pet models, whereas pet is just one App.Pet.
Store in Controller
App.IndexRoute = Ember.Route.extend({
model: function() {
return App.Pet.find(4);
}
});
The router is used to setup the controller, and so we specify here that the IndexController should hold one App.Pet with the ID of 4. This can of course be dynamic. Since your controller represents only one model, it should be of the type ObjectController, but if it was used to store many pets, then it should be of the type ArrayController.
By specify the model, you will have access to it in your IndexController and index view (data-template-name="index"). This is because when you move into your index route, the IndexController is located/instantiated, IndexView is instantiated and placed into the DOM, all after consulting the IndexRoute for setting up the controller.
You can now do something like this in your template (although model. is not necessary): {{model.name}}, which will get you your pet's name.
Display using #each
Find all your pets using a modified version of the above code, but returning all of the pets. Remember, this is done by specifying no arguments to your find method:
App.IndexRoute = Ember.Route.extend({
model: function() {
return App.Pet.find();
}
});
Now we can do loop through all of the pets in the index template. Whilst there are many ways to loop, such as including content./model., excluding .content/model, using this, controller, et cetera..., it's not necessary, but that's for another day. What matters at the moment is that this will work for you, and will be the most self-intuitive:
{{#each pet in controller}}
{{pet.name}}
{{/each}}
I'll put together a jsFiddle for this if you would like. Please let me know.
Questions
Does ember-data have a built in way of retrieving data? If not, where
should the AJAX request be implemented?
Yes, that's Ember Data module which has some good guides on EmberJS.com.
What is the best way to insert the JSON data into the DS model?
Using Ember Data as per the examples up above.
What is the best way to then sync the models up with a Controller?
Using the model hook in the appropriate route to specify which model(s) your controller represents.

jquery Ajax optimization tips - MVC

I am currently trying to convert a controller action into Ajax requests in order to let the page load in sections rather than all at once. Before I started making changes, the page loaded in about 8 seconds (it has to process a lot of information).
Since I've changed it to loading up Partial Views via ajax, the page now takes about 35 seconds to load up the same information.
The process is as follows:
The initial request processes and then returns a viewmodel (a generic list) as json
I then use the returned data to create two partial views
I just wonder if there is a better way of laying out the jquery to get it to work faster. I'm aware the amount of data being passed could be a factor - although I can't find the exact size of the object in the debugger, when I dump the json out to a text file it is about 70kb.
jQuery
$.ajax({
type: 'GET',
dataType: "json",
url: '#Url.Action("GetMapDetails")',
success: function (data) {
$.ajax({
type: 'POST',
contentType: 'application/json',
url: '#Url.Action("GetMapItems")',
data: JSON.stringify({
list: data
}),
success: function (result) {
$("#mapContainer").html(result);
}
});
$.ajax({
type: 'POST',
contentType: 'application/json',
url: '#Url.Action("GetAreaPoints")',
data: JSON.stringify({
list: data
}),
success: function (result) {
$("#areaPointsContainer").html(result);
}
});
}
});
Controller
public JsonResult GetMapDetails()
{
List<ViewModel> vm = new List<ViewModel>();
//create viewmodel here
return Json(vm.ToArray(), JsonRequestBehavior.AllowGet);
}
public ActionResult GetMapItems(List<ViewModel> list)
{
return PartialView("_MapItemsPartial", list);
}
public PartialViewResult GetAreaPoints(List<ViewModel> list)
{
return PartialView("_AreaPointsPartial", list);
}
If anyone can offer some optimization advice, that would be great thanks
You could look into rendering partial views into strings. That way you could return both HTML strings from GetMapDetails, and you'd be able to achieve the same result in one AJAX call instead of three.
If would also rid you the need of serializing the viewmodel back and forth, so there might be some performance gain there.
Install the Stackexchange Miniprofiler and hook it into your database requests as well, this will help you find which bit is taking the most time. I suspect it could well be your data and processing on the server (depending on how you have written your controller you could be hitting your data load+process 4 times in the AJAX version, resulting in the 4 times page load).
If this is true then the problem is not going to be fixed by AJAXing your page but caching the processed data on the server (to keep it up to date your choices are a short cache duration or have the process that updates your data remove the cache, the correct answer depends on what your data is).
Since I think that your goal is to be able to load partial views only when they are needed, putting them all in one markup string isn't going to work.
The performance problem you are having is probably due to the fact that ajax-calls are indeed more performance expensive then to load a result stream from a server.
Caching will only help when you retrieve the same data into the same page - not your case either.
From what it seems to me, you should load up the initial view to the user, and immediately start background pre-loading of the views you are probably going to need soon. Just placing them onto the DOM as an indivisible elements, so one requested, they will be immediately loaded. Of course you pre-load only those which you are most likely to need soon.
Other, probably more effective way, would be to use an MVVM framework on the client, like KnockoutJS. Define your views in a simple html markup, without the actual need for the server to render the partial view with the model. This would allow an html to transfer faster. Separate REST calls from your client would be retrieving only the model data from the server in JSON format, and you will apply data binding to the view (lightweight html you've loaded previously). This way the burden of heavy-rendering will be on the client and the server will be able to service more clients in a long run + you are most likely to get the performance gain.
Also try to use $.ajax cache option to true to improve further calls jQuery ajax method
I assume that infomation don't change fast then it would improve the performance.
For example I work with statistics pages loading asynchronously 7-8 plots there cache saves me a lot of time.
From jQuery Api:
On the other hand if the posted data content changes fast it's not recommended to cache it but also take into account that EVERY browser caches that request in it's own cache. To avoid browsers caching use timestamps on every request as query strings just as $.ajax does automatically.

KnockoutJS best practice to populate multiple view models using Ajax

I was wondering whether anyone had any recommendations regarding populating multiple view models on a screen. I have:
a) a view model that has a list of tasks
b) a view model that has a list of users
I populate these in the 2 x ajax success (separate ajax calls) something like:
success: function (data) {
masterVM.User = ko.mapping.fromJS(data, mapping);
ko.applyBindings(masterVM);
}
/* another ajax call: */
success: function (data) {
masterVM.Task = ko.mapping.fromJS(data, mapping);
ko.applyBindings(masterVM);
}
And currently calling in each ajax success call.
I hope my question is clear and concise. Please ask for further detail if required.
Regards
Phil
We currently handle this by sending all of the data to our page in a single Ajax call, then applying a ko.mapping to map the data to the view models on our main view model.
We began by making two calls just as you are but decided that it would be better to reduce the number of http requests being made, which is why we combined the data sets into a single hierarchical object structure, and it's working great.
This question and the subsequent answer contain a snippet of the approach we're taking:
Map JSON data to Knockout observableArray with specific view model type
As long as you dont notice a performance issue, I recommend making separate calls because this will keep your services loosely coupled with your presentation needs.
However, if its a perf issue, you can make your web service aggregate the data and return it in one shot. But you lose a little maintainability by this.

Resources