AJAX Updates with Angular - ajax

I am trying to implement a polling method in my client that uses AJAX. I am building an ASP.NET framework Web application, wit c# on the backend and I use JavaScript with Angular on the front end, but I am unsure of....
1.) If the code I have will actually do real time updates and update the displayed content on my web page like intended.
2.) If the way I am incorporating Angular into my AJAX request will work.
and 3.) If I need to specify 'get' in the body of the ajax request, like type: 'get';
I have a variable attached to $scope called instruments that I would like to update with the data from the url, and update my webpage if there are any changed to the data. Obviously the url will contain the actual URL where I wish to get data from. Here is my code thus far in my module...
var updates = function update() {
$.ajax({
url: '...',
success: function (data) {
$scope.instruments = data;
},
complete: function () {
setTimeout(update, 5000);
}
});
};

its easy with v_comet packge
import { V_ } from 'v_comet';
/**
title is the variable that need to change.
*/
V_('this.state.title', object); /** in react */
V_('this.title', object); /** in angular */
more details:
https://www.npmjs.com/package/v_comet

Related

Handling session timeouts in ajax calls

ASP.Net MVC 5 .Net Framework 4.6.1
I just added code to detect session timeout which works fine:
public class CheckSessionTimeOutAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext)
{
var context = filterContext.HttpContext;
if (context.Session != null)
{
if (context.Session.IsNewSession)
{
string sessionCookie = context.Request.Headers["Cookie"];
if ((sessionCookie != null) && (sessionCookie.IndexOf("ASP.NET_SessionId", StringComparison.Ordinal) >= 0))
{
string redirectTo = "~/Home/Index";
filterContext.HttpContext.Response.Redirect(redirectTo, true);
}
}
}
base.OnActionExecuting(filterContext);
}
}
As you can see, I redirect them to the home screen. I have my [CheckSessionTimeOut] as an attribute on all pertinent controllers. So, I run the app, go to a page other than the home screen, wait 1 minute for session timeout, the code runs as expected in certain situations. Case and point, I have a dropdown and when a selection is made, a redirect is taking place. Heres the method:
$('#selusers').change(function () {
var rd = $(this).find("option:selected").attr('redirect');
location.href = rd;
});
What happens here is when a user is selected from the dropdown, the redirect attribute is read and redirection to that person takes place. If the session times out, redirection to the logged in user takes place and not the newly selected user. This is correct for my app.
However, I make numerous ajax calls in my app. When the session times out and I click on an element that fires an ajax call, I get redirected to the home screen, but the error method gets called in the ajax request. I get a popup with the home screen html inside of it. Here's one example of an ajax call I'm making. I'm on a screen with a save button, the session times out and this code gets fired:
SaveButtonClicked: function (somedata) {
$.ajax({
url: url,
type: 'POST',
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(some data im sending),
success: function (dataResult) {
if (!dataResult.Ok) {
alert("Error occurred. Please try again");
}
},
error: function (err) {
alert(err.responseText);//this gets called
}
});
}
I have overridden the default alert so styled html will appear. The alert box has the home screen html in it. I do not want that. I want the app to be redirected to the home screen, no popup. So my first question, is there a way to do something at the server to stop the ajax call from running its complete methods(i.e I want to do something at the server so the ajax call's success, error, or complete methods will never be called)? Next question if the first one isn't an option, what would be a very good way to detect that the session has timed out in the complete methods of an ajax call so the user is gracefully redirected to the home screen? If there are any other ways of doing what i'm trying to achieve that I didn't not ask, please share them. Thank you for reading my question.
UPDATE
I removed the error function from one of my ajax calls and added a global error handler instead:
$(document).ajaxError(function (e, xhr, settings) {
debugger;
});
Now, when the session timeout, this error handler gets called, BUT, i look in the xhr variable and it contains the results of the ajax call and corresponding html. The status is a 200, the statusText says parsererror, the readystate is a 4. There is nothing here that tells me the session timed out. What can i do at the global ajaxError method to tell me session timed out?
A good starting points might be:
If your ASP.NET MVC project properly returns status code:
$.ajaxSetup({
statusCode: {
401: function() {
window.location.href = "/login/path";
}
}
});
if not you can try:
$(document).ajaxError(function (e, xhr, settings) {
debugger;
});
Review e & xhr properties and make a decision from there.

Is Backbone.js suitable for getting HTML from server?

As far as I can tell, Backbone.js view represents DOM element. I take it from existing DOM or create it on the fly in el attribute.
In my case, I want to take it from server with AJAX request because I'm using Django templates and don't want to rewrite everything to JavaScript templates.
So I define el function that performs AJAX request.
el: function() {
model.fetch().success(function(response) {
return response.template
})
}
Of course, it does NOT work because AJAX request is executed asynchronous.
This means that I don't have el attribute and events does NOT work neither. Can I fix it?
Maybe the Backbone.js framework isn't the right tool for my needs? The reason I want to use that was to have some structure for the code.
P.S. I'm new to Backbone.js.
Do your ajax request from another view, or directly after the page load using jquery directly, and after you've downloaded your template, THEN instantiate your backbone view class with the proper id/el or whatever (depending on where you stored your ajax fetched template). Depending on your use-case, this may or may not be a sensible approach.
Another, perhaps more typical approach, would be to set up your view with some placeholder element (saying "loading" or whatever), then fire off the ajax, and after the updated template has been retrieved, then update your view accordingly (replace the placeholder with the actual template you requested).
When/if you update your view with new/other DOM elements, you need to call the view's delegateEvents method to rebind your events to the new elements, see:
http://backbonejs.org/#View-delegateEvents
I came across a similar requirement. In my instance, I was running asp.net and wanted to pull my templates from user controls. The first thing I would recommend is looking into Marionette because it will save you from writing a lot of boiler plate code in Backbone. The next step is to override how your templates are loaded. In this case I created a function that uses Ajax to retrieve the HTML from the server. I found an example of this function where they were using it to pull down html pages so I did a little modification so I can make MVC type requests. I can't remember where I found the idea from; otherwise, I would give the link here.
function JackTemplateLoader(params) {
if (typeof params === 'undefined') params = {};
var TEMPLATE_DIR = params.dir || '';
var file_cache = {};
function get_filename(name) {
if (name.indexOf('-') > -1) name = name.substring(0, name.indexOf('-'));
return TEMPLATE_DIR + name;
}
this.get_template = function (name) {
var template;
var file = get_filename(name);
var file_content;
var result;
if (!(file_content = file_cache[name])) {
$.ajax({
url: file,
async: false,
success: function (data) {
file_content = data; // wrap top-level templates for selection
file_cache[name] = file_content;
}
});
}
//return file_content.find('#' + name).html();
return file_content;
}
this.clear_cache = function () {
template_cache = {};
};
}
The third step would be to override Marionette's method to load templates. I did this in the app.addInitializer method. Here I am initializing my template loader and setting it's directory to a route handler. So when I want to load a template, I just set the template: "templatename" in my view and Backbone will load the template from api/ApplicationScreens/templatename. I am also overriding my template compiling to use Handlebars because ASP.net is not impressed with the <%= %> syntax.
app.JackTemplateLoader = new JackTemplateLoader({ dir: "/api/ApplicationScreens/", ext: '' });
Backbone.Marionette.TemplateCache.prototype.loadTemplate = function (name) {
if (name == undefined) {
return "";
} else {
var template = app.JackTemplateLoader.get_template(name);
return template;
}
};
// compiling
Backbone.Marionette.TemplateCache.prototype.compileTemplate = function (rawTemplate) {
var compiled = Handlebars.compile(rawTemplate);
return compiled;
};
// rendering
Backbone.Marionette.Renderer.render = function (template, data) {
var template = Marionette.TemplateCache.get(template);
return template(data);
}
Hopefully this helps. I've been working on a large dynamic website and it is coming along very nicely. I am constantly being surprised by the overall functionality and flow of using Marionette and Backbone.js.

How to parse JSON using DOJO AJAX and REST

I am trying to send a request to a REST server using DOJO AJAX, however I get a null object as result (console):
You CLICKED = click clientX=34, clientY=13
JSON loaded from server: null
Here is my code:
// JavaScript Document
// load requirements for declarative widgets in page content
require([ "dojo/parser",
"dojo/dom",
"dojo/domReady!",
"dijit/form/Button"
]);
// Start initializing
dojo.ready(function(){
dojo.connect (
aBut1,
"onClick",
function(e){
console.log('You CLICKED = ', e);
dojo.xhrGet({
// The URL of the request
url: "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer/find",
// Handle the result as JSON data
handleAs: "json",
// content
content: {f:"json", searchText:"new", contains:"true", searchFields:"state_new", layers:"2", returnGeometry:"false" },
// The success handler
load: function(jsonData) {
// Create a local var to append content to
console.info("JSON loaded from server: ", jsonData);
},
// The error handler
error: function() {
console.log('JSON log Error');
}
});
});
}); // End dojo.ready
This is the REST url I would like to use:
http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer/find?searchText=new&contains=true&searchFields=state_name&sr=&layers=2&returnGeometry=false&f=json
I save the result of this URL in a json file and AJAX works reading that file and returning an object with 4 items. It is not using REST URL.
Thank you
I believe you are trying to use dojo.xhrGet to access a different domain, which it cannot do.
Limitations
dojo.xhrGet (and other functions in the same line: dojo.xhrPost,
dojo.xhrDelete, dojo.xhrPut), are bound by the ‘same domain’ security
policy of the browser. This means that they can only establish a
connection back to the same server that served the HTML page. If you
wish to use this API to talk to servers other than the one that
originated your page, then you will have to use a proxy on your
originating server and have it forward the requests. The only other
solution to working around the same domain restriction is to use
alternate IO methods, such as dojo.io.script.
http://dojotoolkit.org/reference-guide/1.7/dojo/xhrGet.html
That's not much to go on. What happens if you use curl to make a request to that URL?
Are you using Dojo 1.7? If so, maybe the Ajax Quickstart docs can help (I linked directly to the AMD-style, since that's probably what you should be using if you can). There are also more detailed docs on xhrGet.

Angular JS data not populated from asynchronous http request

I am trying to get a loading div to show when my angular module is contacting the server. I am using AngularJS 1.0.1 and AngularJS Resources 1.0.1 to expand the functionality of the HTML and jquery 1.7.2 for some additional dom manipulation and ajax support.
I already found out that the loading div will not show if I run the ajax call in async false, except for Firefox where it shows but animated gif is not animated.
If I run the ajax call in async true, the data returned back does not get loaded into the angular model variables of the loaded template partial.
Is it at all possible to get an animated loading div to show and get the angular data to load into the model?
Hopefully I'm understanding you correctly. You want to show a loading progress for your ajax requests. To do this you need a response interceptor. Here is a an example of how to do this http://jsfiddle.net/zdam/dBR2r/
// register the interceptor as a service, intercepts ALL angular ajax http calls
.factory('myHttpInterceptor', function ($q, $window, $rootScope) {
return function (promise) {
$rootScope.nowloading = true; // use ng-show="nowloading" on element containing spinner
return promise.then(function (response) {
// do something on success
$rootScope.nowloading = false; // need to turn it off on success
return response;
}, function (response) {
// do something on error
$rootScope.nowloading = false; // need to turn it off on failure
$rootScope.network_error = true; // you might want to show an error icon.
return $q.reject(response);
});
};
hope this helps
--dan

ASP.NET MVC 3 display list of object without reloading web page

I have ASP.NET MVC 3 web app and List of objects
List<ConversionModel> Queue
I would like to display list of ConversionModel objects in one web page and refresh display every five seconds without reloading web page. I am new to MVC 3 and can't find any example.
You could use AJAX for this, but I don't think that has a good impact on your server (at least doing so every five seconds for every user on your site).
Client-side:
<script type="text/javascript">
// This is to refresh the items every 5 seconds (5000 milliseconds)
setInterval(getMyData, 5000);
function getMyData() {
// Using $.getJSON for simplicity, but try to use $.ajax or $.post
$.getJSON('/MyController/MyAction', function(response) {
var items = response.d.items;
// Iterate through the items here and add the items to your web page
});
}
</script>
Server-side:
public JsonResult MyAction()
{
List<ConversionModel> conversionModels = GetMyDataSomewhere();
return Json(new {
items = conversionModels
}, JsonRequestBehaviour.AllowGet);
}
If updating the view each five seconds is all you need, you could get away with simple ajax combined with a timer. See
jQuery ajax function
JavaScript setTimeout() function
Third, you will need to have an action method in one of your controllers fetching the set of ConversionModels from the database and generating a response from it (either JSON or directly a HTML markup).
If you read the documentation for the $.ajax() function, I believe you will see how the pieces fit in together.
If, however, you want to be more flexible than just polling the server each five seconds regardless of the real activity, you may want to check on SignalR, a great library for pushing data from server to the client (e.g. a browser).
use jQuery an make ajax requests every x minutes to the controller that will return a partial view with a model as List.
javascript on your main page could look like this:
function timerMethod() {
$.ajax({
type: "get"
url: "/Controller/Action",
cache: false,
success: function(result){
$("#partialContainer").html(result);
}
});
var timerId = setInterval(timerMethod, 5000); // 5 seconds
Controller/Action is your action that return partial view.
You also need to create a view with name Action in Views\Controller and write it so that it displays all the objects in the model (model should be of type List<ConversionModel>). Hope that helps

Resources