How to Update Model in AngularJS when Ajax used Long Polling? - javascript

How to update the model when i used ajax long polling technique?
At first i will load the default list
Example:
- id1
- id2
- id3
Then in my background process, i setup a ajax long polling that will run every 5seconds interval.
When the ajax receive an update it will update the display in angularjs accordingly without refreshing page.
So from the example below, when i receive changes, it should output something like this:
Example:
- id1
- im New Here..
- id3
Is that possible using this technique?.. without using any websocket or nodejs...
Thanks

Yes it's possible.
I assume you want to do a GET request every 5 seconds so not really keeping your connection open constantly.
If you place the request method inside your scope you could do something like this:
$scope.ids = ['id1','id2','id'3]; //by initial request.
postFunction() {
//Request here
var newData = request.data;
$scope.ids.push(newData);
}
Since Angular modals use 2way databinding your html gets updated instantly.

Related

Load data with AJAX only if it has not already been loaded?

I need to load data for my JavaScript app to use. I would like to load the following:
userlist JSON
milestones JSON
Tags JSON
user ACL permissions JSON
These 4 items of data from the server as JSON should be loaded using AJAX but only loaded once.
So I need code that will check to see if the data is loaded already and if it is, use it. If it is not loaded yet, it would make an AJAX request and load the data, and then use it.
I have multiple JavaScript files which need access to this data so I want to make sure that any of them can access it, and whichever once calls for it first will load it using AJAX and make it available for the other scripts to call it without making multiple repeat AJAX requests.
How could I go about this using JavaScript and jQuery?
A basic example would be super appreciated and useful. Thank you
If any of these are not set, load them using AJAX. After loading with AJAX, set these vars for the next caller to access them without a new AJAX request being made...
var userList = userJsonData;
var milestoneList = milestoneJsonData;
var tagList = tagJsonData;
var useAclPermissions = useAclPermissionsJsonData;
Just store the data in a global javascript variable, which is set to null, when your page loads. The first script which loads the data, stores it in the variable, all the other scripts try to access the content of the variable, and if not set, load it:
var milestoneData = null;
function getMilestoneData() {
if (milestoneData === null) {
//make the ajax request, and populate milestoneData variable
} else return milestoneData;
}
According to can i use you can check out localstorage aka webstorage. If you can use it, it might solve your issues. There is a jQuery plugin available. jstorage is an alternative, and has a really simple example at the bottom of the page. Hope this helps.

Execute javascript inside the target of an Ajax Call Drag and Drop Shopping Cart without Server language

Well i wanna create an Ajax Drag and Drop Shopping cart using only javascript and ajax. Currently i'm using the example in this page as a stepping stone. Right now it's only with local jquery and it works fine but i want to make the cart work with ajax calls. Note that i do not want to use a server side language( like php, rubby, asp etc), only html and javascript.
My initial thought was that at the $(".basket").droppable i should add an ajax call to another html page containing the "server logic" in javascript, execute in that file all the necessary steps( like reading the get variables (product name, product id and quantity), set a cookie and then return an ok response back. When the server got the "ok" response it should "reload" the cart div with the updated info stored inside the cookie.
If this was with php i would know how to do it. The problem is that as far as i know, you can execute javascript once it reaches the DOM, but how can you execute that js from inside the page that isbeing called upon ? ( thanks to Amadan for the correction)
I've thought about loading the script using $.getScript( "ajax/test.js", function( data, textStatus, jqxhr ).. but the problem with that is that the url GET variables i want to pass to the "server script" do not exist in that page.
I havent implemented all the functionality yet as i am stuck in how to first achieve javascript execution inside an ajax target page.
Below is a very basic form of my logic so far
// read GET variables
var product = getQueryVariable("product");
var id = getQueryVariable("id");
var quantity= getQueryVariable("quantity");
//To DO
//--- here eill go all the logic regarding cookie handling
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if (pair[0] == variable) {
return pair[1];
}
}
alert('Query Variable ' + variable + ' not found');
}
Any help regarding this matter will be appreciated.
Note: Logic in simple words:
1)have an html page with products+cart
2)Have an "addtocart.html" with the "Cart Server Logic"( being the target of the ajax call when an item is dropped into the product.)
If you have some other idea on this, please enlighten me :)
thanks in advance
Foot Note-1:
if i try loading the scipt using
$("#response").load("ajax/addtocart.html?"+ $.param({
product: product,
id: id,
quantity:quantity
})
);
i get the alert about not being able to find the url parameters( something that i thing is normal as because the content is being loaded into the initial page, from which the request is started, there are no get parameters in the url in the first place)
The problem is that as far as i know, you cannot execute javascript contained in the target of an ajax call, as that page never reaches the browser interpreter.
This is either incorrect or misleading. The browser will execute any JavaScript that enters DOM. Thus, you can use $.load to load content and execute code at the same time. Alternately, you can use hacked JSONP to both execute code and also provide content as a JSON document.
EDIT: Yes, you can't get to the AJAX parameters from JavaScript. Why do you want to? Do you have a good reason for it, or is it an XY problem?
The way I'd do it is this:
$('#response').load(url, data, function() {
onAddedToCart(product, id, quantity);
});
and wrap your JS code in your HTML into the onAddedToCart function.
Depending on what exactly you're doing, it could be simplified even further, but this should be enough to cover your use case.

Rails/JS - get variable without page refresh

In my app I have a variable which is an integer. The variable is constantly changing and I want it to always show the current integer when a user is on the site without them having to keep refreshing the page.
I know there are a few ways to do this, but what would be the easiest and most unobtrusive way to accomplish this?
For easy sake lets make this the integer
#foo = Post.all
I would supply some code but after research elsewhere I still haven't been able to try and solve this.
Thanks.
As far as I know, server can't send information to client without request from client. So, you can set up regular AJAX requestes for that.
Firstly, you should make separate action in controller, that return your integer in json
def foo_update
#foo = some_new_value
render json: #foo
end
In you .js files set Interval and AJAX request
var ajax_foo_update = function(){
$.get("/controller_name/foo_update",function(data){
$("#elem_to_place_foo").html(data.integer);
});
}
$(function(){
setInterval(ajax_foo_update, 10000);
});
This function will be updating foo every 10 seconds. Also, you #foo should look somehow like {integer: 5}
Don't forget to write right routes.

ScriptManager.RegisterStartupScript Keeps adding script blocks multiple times

I have an update panel with a timer control set up to automatically check for some data updates every minute or so.
If it sees that the data updates, it is set to call a local script with the serialized JSON data.
ScriptManager.RegisterStartupScript(UpdateField, GetType(HiddenField), ACTION_CheckHistoryVersion, "updateData(" & data & ");", True)
where "data" might look something like
{
"someProperty":"foo",
"someOtherProperty":"bar",
"someList":[
{"prop1":"value"},
{"prop2":"value"}, ...
],
"someOtherList":[{},...,{}]
}
"data" can get quite large, and sometimes only a few items change.
The problem I am having is this. Every time I send this back to the client, it gets added as a brand new script block and the existing blocks do not get removed or replaced.
output looks something like this:
<script type="text/javascript">
updateData({
"someProperty":"foo",
"someOtherProperty":"bar",
"someList":[
{"prop1":"value"},
{"prop2":"value"}, ...
],
"someOtherList":[{},...,{}]
});
</script>
<script type="text/javascript">
updateData({
"someProperty":"foo",
"someOtherProperty":"bar",
"someList":[
{"prop1":"changed"},
{"prop2":"val"}, ...
],
"someOtherList":[{},...,{}]
});
</script>
<script type="text/javascript">
updateData({
"someProperty":"foos",
"someOtherProperty":"ball",
"someList":[
{"prop1":"changed"},
{"prop2":"val"}, ...
]
});
</script>
with a new script block being created every time there is a change in the data.
Over time the amount of data accumulating on the browser could get potentially huge if we just keep adding this and I can't imagine how most people's browser would take it, but I don't think it could be good.
Does anyone know if there is a way to just replace the code that has been sent back to the browser rather than continuously adding it like this?
I came up with a hack that seems to work in my situation.
I am using jQuery to find the script tag that I am creating and remove it after it has been called.
Here is an example:
First I generate a guid:
Dim guidText as string = GUID.NewGuid().ToString()
I create a function like the following:
function RemoveThisScript(guid){
$("script").each(function(){
var _this = $(this);
if(_this.html().indexOf(guid)>-1)
_this.remove();
});
}
Then I add the following code to my output string:
... & " RemoveThisScript('" & guidText & "');"
This causes jQuery to look through all the scripts on the page for one that has the GUID (essentially the one calling the function) and removes it from the DOM.
I would recommend to use web service with some webmethod which you will call inside window.setInterval. In success handler of your webmethod (on client side) you can just take response and do whatever you want with it. And it will not be saved in your page (well, if you will do everything wrong). Benefit is that you will minimize request size(updatepanel will pass all your viewstate data, which could be large enough) and will limit server resources usage (update panel is causing full page live cycle, suppose slightly modified, but anyway - all those page_load, page_init, etc...) and with web service you will only what you need.
Here is an article where you can see how it could be created and used on client side. Looks like good enough.

What is the best way to paginate xml results using jQuery?

I am using jQuery to get results, as xml, from a MySQL database. What is the best way to paginate the results?
Right now my script gets the xml and appends each result as a <li> element to a <ul> element.
I'm guessing it will have something to do with creating a global var that gets changed with the next/previous page button that runs a script to remove, then re-append the correct results range, but I'm not really sure.
You shouldn't make pagination dependent on Javascript, it should be done server-side instead. So, for example, the server could return a "next" link that would be something like View next 50 results. The script would take that variable of 50 and return the 50 next results and the link would then be returned as results.php?entry=100. You could integrate this with Ajax so the results would come back without a page refresh, however, but the pagination itself would still be done in the backend.
i would do something like this
var numRows = $table.find('tbody tr').length
var numPages = Math.ceil(numRows / numPerPage)
var $pager = $('</p><br>
<div class="pager"></div>
')
for (var page = 0 page < numPages page++) {
$('<span class="page-number">' + (page + 1) + '</span>')
.appendTo($pager).addClass('clickable')
}
$pager.insertBefore($table)
There are a few plugins, but you're on the right track. When you do the remove/re-append thing, do a $('#mydiv').load('/path/to/myfile.php'). Pass your file the start and stop points, which would serve as the points in your array from which to grab your data.
function paginate(start, limit) {
// Maybe show a preloader?
$('#loader').show();
$("#mydiv").load("/path/to/myfile.php", {start: start, end: limit}, function(){
// hide preloader or do other code here
$('#loader').hide();
});
}
Do you get the entire result set (all the pages) in one go, or do you get one page at a time? In any case you should keep a local cache of the data you received from the server and use that when the user navigates the pages. For example, if you retrieve one page at a time, and the user goes from page 1 to page 2, then you need to retrieve page 2 from the server. But if the user now goes back to page 1, then you should load that from the cache. If the user goes to page 3, then you should fetch that from the server and add it to the cache.
Next I would separate the logic for displaying a single page to the user and fetching a page from the server. When the user clicks on the next page button, you should ask the cache object for the next page, but don't return anything. Instead the cache will call a callback function once it has data. If the data is in the cache, it would call the callback function immediately, passing the result as an argument. The callback function would then update the view presented to the user. If the data is not in the cache, an ajax request is made to the server for that data. Once the data is retrieved, the callback function would be called.
I'm usually against using xml with ajax (I prefer ajaj; Asynchronous JavaScript and JSON. It's also a lot more fun to say out loud). JSON is a better alternative, because it's a lot easier to work with in JavaScript, it takes up less space, both in memory and during transport. Since JSON objects are normal JavaScript objects, adding them to a local cache is as easy as concatenating two arrays (the cache you already have and the new elements retrieved from the server).

Categories

Resources