Using JavaScript objects and AJAX vs ASP MVC3 Model - javascript

Since I am fairly new to MVC, I am a little confused as to what is the proper/preferred way of using MVC's Models together with JavaScript objects and AJAX.
As an example, I have an application that displays a calendar with user's events, which are stored in the database. On top of that, these events can be manipulated by moving them around the calendar and then the new times are saved in the database.
When the user first makes a call to my Calendar action, I load the events from the database and then pass them to the view via the CalendarModel. This allows me to prepare these events visually but now I also need these events to be available as JavaScript objects because I will use AJAX calls to my UpdateEventTimes action to persist user's changes.
So my options today are to either "extract" the events' data from the CalendarModel and "hardcode" them as a string in JavaScript code or perform an AJAX call from JavaScript to retrieve these events again. Needless to say, I like neither approach so I am wondering if there is some MVC trickery that I am missing that's more elegant?

Unfortunately there isn't any. The only option to archive your scenario is to build js from Model like this:
<script>
var events = #(Model.Events.Aggregate(<aggregation function here to build js object>)) ;
</script>

Related

JavaScript: Timer to refresh content of elements with same class

There is a web app I am designing. I'm using AngularJS on the front-end with a Java back-end. The web app is being deployed in a war file to a local JBoss server. I currently have a Java class that performs a series of calculations and sends that data as JSON to the client every 10 seconds. This works, but I want to update the elements that contain this data with AJAX(?).
In Angular I have a few $resource services that consume the Java RESTful API. This is all JSON data, which is the being propagated into the view by a single controller. I then have some HTML elements generated by ng-repeat that all have the same classes. I wanted to use one of these classes to trigger a refresh on all of the elements every 10 seconds. Here is a snippet with the ng-repeat I am talking about:
<div ng-repeat="mq in mqDepth">
<progressbar class="mq" max="max" value="dynamic" ng-init="dynamic=mq.currentDepth" type="info>
<span>
{{dynamic}} / {{max}}
</span>
</progressbar>
</div>
In the above snippet, the data that's being updated is mq.currentDepth.
And this is the code I am using to refresh:
function refreshQueue() {
$('.mq').load('', function() {
$(this).unwrap();
});
}
refreshQueue();
setInterval(function() {
refreshQueue();
}, 10000);
I get a warning that basically states the way I am implementing AJAX will break my user interface, which it does after a series of updates.
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/.
I have a few questions
Can you update the contents of an element with a class in AJAX, or does that only work with IDs?
Should I be using AJAX to refresh the page?
If not, then how would I implement that with Angular?
Doing synchronous network calls from javascirpt will block the main thread, which may block your UI and hence is not adviced. To answer your questions.
When you are using angular, you shouldn't access the elements using class or ids (using selectors), the way we use to do with jQuery. Instead you should use data-binding.
You do not need AJAX to refresh the page.
You can use your existing $resources for retrieving data. Once you have the data in controller, save that in a scope variable. Then you can use the same variables in your HTML using angular-expression to update the data.
$scope.mqDepth = MqDepth.get({ id: id });

Spring MVC Ajax Request to Refresh Dynamic Table

I currently have a spring mvc app that gets a list of users from a database and displays their information in a table using JSP to basically loop through each object in the list and create a table row for them.
Each user has an expiry date attribute as part of their record in the database. What I want to achieve is basically a button that when toggled shows or hides all users that have expired (i.e. their expiry date is less than today's date).
For this I am trying to use AJAX calls to my controller to fetch me all users expired or not OR only users that haven't expired depending on how the button is toggled.
What I would like help on is the best way to achieve this as I can think of a few nasty ways of doing it like having a separate page and refreshing but I am confused on a few things.
Should I just ditch the JSP looping through to make the table and make a method in JavaScript that creates that table when given the data? If so how do I get the data from the controller to JavaScript, can an AJAX call to a controller return me a list of my user objects?
My best guess is that instead of adding a list of objects to a model and letting JSP do the work, that I instead return a JSON with the data and use JavaScript to build the table. I can then call an update method to re-build the table.
You are correct. You have 2 options:
Have AJAX call return html (i.e. jsp) for the table and then replace
the body of the table
Use JavaScript to build the table and then
update the table with AJAX call which returns JSON.
If you want to get more sophisticated, you could use a JavaScript framework like Knockout.js which would let you mark up the table and refresh the table without too much of JavaScript writing.
Blurgh I'm not sure why this question has received so much attention, especially now in the days of angular but if you are struggling with this then I would strongly recommend the following library:
https://www.ag-grid.com/

Page Load alternative in a Pure HTML AJAX Website

I am working on a pure HTML website, all pages are HTML with no relation to any server side code.
Basically every request to the server is made using AJAX, I send data from forms, I process this data in Handlers, then I return a JSON string that will be processed back on the client side.
Let's say the page is loaded with parameters in the URL, something like question.html?id=1. Earlier, I used to read this query string on Page Load method, then read data from the database and so on...
Now, since its pure HTML pages, I'm trying to think of an approach that will allow me to do the same, I have an idea but its 99% a bad idea.
The idea is to read URL parameters using JS (after the page has loaded), and then make an AJAX request, and then fetch the data and show them on the page. I know that instead of having 1 request to the server (Web Forms), we are now having 2 Requests, the first request to get the page, and the second request is the AJAX request. And of course this has lots of delays, since the page will be loaded at the beginning without the actual data that I need inside it.
Is my goal impossible or there's a mature approach out there?
Is my goal impossible or there's a mature approach out there?
Lately there are a good handful of JavaScript frameworks designed around this very concept ("single page app") of having a page load up without any data pre-loaded in it, and accessing all of the data over AJAX. Some examples of such frameworks are AngularJS, Backbone.js, Ember.js, and Knockout. So no, this is not at all impossible. I recommend learning about these frameworks and others to find one that seems right for the site you are making.
The idea is to read URL parameters using JS (after the page has loaded), and then make an AJAX request, and then fetch the data and show them on the page.
This sounds like a fine idea.
Here is an example of how you can use JavaScript to extract the query parameters from the current page's URL.
I know that instead of having 1 request to the server (Web Forms), we are now having 2 Requests, the first request to get the page, and the second request is the AJAX request. And of course this has lots of delays, since the page will be loaded at the beginning without the actual data that I need inside it.
Here is why you should not worry about this:
A user's browser will generally cache the HTML file and associated JavaScript files, so the second time they visit your site, the browser will send requests to check whether the files have been modified. If not, the server will send back a short message simply saying that they have not been modified and the files will not need to be transmitted again.
The AJAX response will only contain the data that the page needs and none of the markup. So retrieving a page generated on the server would involve more data transfer than an approach that combines a cacheable .html file and an AJAX request.
So the total load time should be less even if you make two requests instead of one. If you are concerned that the user will see a page with no content while the AJAX data is loading, you can (a) have the page be completely blank while the data is loading (as long as it's not too slow, this should not be a problem), or (b) Throw up a splash screen to tell the user that the page is loading. Again, users should generally not have a problem with a small amount of load time at the beginning if the page is speedy after that.
I think you are overthinking it. I'd bet that the combined two calls that you are worried about are going to run in roughly the same amount of time as the single webforms page_load would if you coded otherwise - only difference now being that the initial page load is going to be really fast (because you are only loading a lightweight, html/css/images page with no slowdown for running any server code.
Common solution would be to then have a 'spinner' or some sort (an animated GIF) that gives the user an visual indication that the page isn't done loading while your ajax calls wait to complete.
Watch a typical page load done from almost any major website in any language, you are going to see many, many requests that make up a single page being loaded, wether it be pulling css/images from a CDN, js from a CDN, loading google analytics, advertisements from ad networks etc. Trying to get 100% of your page to load in a single call is not really a goal you should be worried about.
I don't think the 2-requests is a "bad idea" at all. In fact there is no other solution if you want to use only static HTML + AJAX (that is the moderm approach to web development since this allow to reuse AJAX request for other non-HTML clients like Android or iOS native apps). Also performance is very relative. If your client can cache the first static HTML it will be much faster compared to server-generated approach even if two requests are needed. Just use a network profiler to convince yourself.
What you can do if you don't want the user to notice any lag in the GUI is to use a generic script that shows a popup hiding/blocking all the full window (maybe with a "please wait") until the second request with the AJAX is received and a "data-received" (or similar) event is triggered in the AJAX callback.
EDIT:
I think that probably what you need is to convert your website into a webapp using a manifest to list "cacheable" static content. Then query your server only for dynamic (AJAX) data:
http://diveintohtml5.info/offline.html
(IE 10+ also support Webapp manifests)
Moderm browsers will read the manifest to know whether they need to reload static content or not. Using a webapp manifest will also allow to integrate your web site within the OS. For example, on Android it will be listed in the recent-task list (otherwise only your browser, not your app is shown) and the user can add a shorcut to the desktop.
So, you have static HTMLs and user server side code only in handlers? Why you can't have one ASP .Net page (generated on server side) to load initial data and all other data will be processed using AJAX requests?
if its possible to use any backed logic to determine what to load on server side, that will be easy to get the data.
say for example if you to load json a int he page cc.php by calling the page cc.php?json=a, you can determine from the PHP code to put a json into the page it self and use as object in your HTML page
if you are using query string to read and determine, what to load you have to make two calls.
The primary thing you appear to want is what is known as a router.
Since you seem to want to keep things fairly bare metal, the traditional answer would be Backbone.js. If you want even faster and leaner then the optimised Backbone fork ExoSkeleton might be just the ticket but it doesn't have the following that Backbone proper has. Certainly better than cooking your own thing.
There are some fine frameworks around, like Ember and Angular which have large user bases. I've been using Ember recently for a fairly complex application as it has a very sophisticated router, but based on my experiences I'm more aligned with the architecture available today in React/Flux (not just React but the architectural pattern of Flux).
React/Flux with one of the add-on router components will take you very far (Facebook/Instrgram) and in my view offers a superior architecture for web applications than traditional MVC; it is currently the fastest framework for updating the DOM and also allows isomorphic applications (run on both client and server). This represents the so called "holy grail" of web apps as it sends the initial rendered page from the server and avoids any delays due to framework loading, subsequent interactions then use ajax.
Above all, checkout some of the frameworks and find what works best for you. You may find some value comparing framework implementations over at TodoMVC but in my view the Todo app is far too simple and contrived to really show how the different frameworks shine.
My own evolution has been jQuery -> Backbone -> Backbone + Marionette -> Ember -> React/Flux so don't expect to get a good handle on what matters most to you until you have used a few frameworks in anger.
The main issue is from a UX / UI point of view.
Once you get your data from the server (in Ajax) after the page has been loaded - you'll get a "flickering" behavior, once the data is injected into the page.
You can solve this by presenting the page only after the data has arrived, OR use a pre-loader of some kind - to let the user know that the page is still getting its data, but then you'll have a performance issue as you already mentioned.
The ideal solution in this case is to get the "basic" data that the page needs (on the first request to the server), and manipulate it via the client - thus ease-in the "flickering" behavior.
It's the consideration between performance and "flickering" / pre-loading indication.
The most popular library for this SPA (Single Page Application) page - is angularJS
If I understand your inquiry correctly. You might want to look more about:
1) window.location.hash
Instead of using the "?", you can make use of the "#" to manipulate your page based on query string.
Reference: How to change the querystring on the same page without postback
2) hashchange event
This event fires whenever there's a changed in the fragment/hash("#") of the url. Also, you might want to track the hash to compare between the previous hash value and the current hash value.
e.g.
$(window).on('hashchange', function () {
//your manipulation for query string goes here...
prevHash = location.hash;
});
var prevHash = location.hash; //For tracking the previous hash.
Reference: On - window.location.hash - Change?
3) For client-side entry-point or similar to server-side PageLoad, you may make use of this,
e.g.
/* Appends a method - to be called after the page(from server) has been loaded. */
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function () {
if (oldonload) {
oldonload();
}
func();
}
}
}
function YourPage_PageLoad()
{
//your code goes here...
}
//Client entry-point
addLoadEvent(YourPage_PageLoad);
Since you're doing pure ajax, the benefit of this technique is you would be able to easily handle the previous/next button click events from the browser and present the proper data/page to the user.
I would prefer AngularJS. This will be a good technology and you can do pagination with one HTML. So i think this will be good framework for you as your using static content.
In AngularJS MVC concept is there please read the AngularJS Tutorial. So this framework will be worth for your new project. Happy coding

Are there any Backbone.js tutorials that teach ".sync" with the server?

I read many Backbone.js tutorials, but most of them deal with static objects.
Of course, I have data on the server. I want a tutorial that shows how backbone.js can communicate with the server to fetch data, post data, etc.
This is .sync, right? I read the backbone.js documentation, but still fuzzy on how to use this feature.
Or can someone show me an example?
According to: http://documentcloud.github.com/backbone/#Sync
Backbone.sync is the function that Backbone calls every time it
attempts to read or save a model to the server.
But when? Where do I put the function? I don't know how to use it, and the documentation doesn't give any examples. When does the data get loaded into my models? I get to define when...right?
You never really have to look at .sync, unless you plan to overwrite it. For normal uses, you can simply call model.save() whenever you want and that will execute a post or put (depending on whether the record exists already). If you want to get the data from your backend, use collection.fetch()
You'll of course also need to specify a URL, do so through your collection attribute, collection.url
You can override Backbones native sync functionality if you override it:
Backbone.sync = function() {
//Your custom impl here
}
After that this function is called whenever you call a backbone function like .save() on models or .fetch() on collections. You do not have to care about data transport anymore.
I would suggest taking a look into Backbones source and look how the default sync function is implemented. Then create your own or adopt your server to support the native function.
They are not free, but the following screencasts both have a piece on backend work and how to send data to and get data from Backbone.
Tekpub is a 9 part screencast about asp.net MVC3, with the whole 6th part about using backbone to write an admin module to manage productions. it shows all about handling routing in MVC3 and sending & receiving data
Peepcode
http://peepcode.com/products/backbone-js about basic backbone stuff
http://peepcode.com/products/backbone-ii about interactivity
http://peepcode.com/products/backbone-iii about persistance (it's this third one you will need for server connection information).

Best practice for rails-javascript interaction?

I have a page which shows a Google map. I'd like to use Javascript to fetch several points from my database and place them as markers on the map. So the flow is:
Javascript calls a Rails action with parameters.
Rails queries the database.
Rails returns the response.
Javascript updates the page (Rails can't do this since it must be aware of the JS map object).
What is the current best practice for implementing such a scenario? I know I can use a Prototype Ajax.Request to call the Rails action but how should I call the Javascript function which updates the page when the Rails action returns its results? Should I update some hidden HTML and have an event listener listen on it? Or is there a better way?
You have a couple options.
1) Your ajax request can be of type 'script' which will allow you to write an action_name.js file that your rails app renders. This has access to all of your page items (it's not likely to have access to your map object however unless that's public)
2) My preferences is to have your javascript query for json data (type 'json') which then allows you to use that data as you please in your JS. I don't use prototype but the general flow would be.
initialize your map
query for some json data using ajax (ie. locations with lat/long)
rails reponds_to do |f| f.json { render :json => some_hash} end
in your ajax callback (back in javascript), iterate over json data and add points to your map appropriately. (or do whatever you like)

Categories

Resources