I am currently trying to update my twitter feed every 1 minute for example.
But I have no idea how to.
This is my ViewModel:
var savedLists = ['NielsenRamon', 'Wouter_Willaert', 'AWT_Centric'];
var twitterListModel = function(list) {
this.savedLists = ko.observableArray(list);
this.currentTweets = ko.observableArray([]);
ko.computed(function() {
twitterApi.getTweetsForUsers(savedLists, this.currentTweets);
}, this).extend({ throttle: 1 });
}
ko.applyBindings(new twitterListModel(savedLists));
I'm using a very minified version of this :http://knockoutjs.com/examples/twitter.html
the API i use is also the same.
What I want is that the bindings on my html page get updated every minute for example without refreshing my page. For example: when someone tweets. That tweet get displayed on the page after 1 minute without refreshing the page.
Is this possible the way I am working now?
Thanks in advance!
You could use a setInterval that calls twitterApi.getTweetsForUsers every minute.
Something like: setInterval(function() { twitterApi.getTweetsForUsers(savedLists, twitterListModel.currentTweets); }, 60000);
If the calls can take a while though, then you might want to modify the twitterApi sample code and use a setTimeout in the callback from the actual twitter API calls that reschedules itself with a new setTimeout.
Related
I am working on offline support in my PWA app. I am using workbox for that. This is my current code:
const addToFormPlugin = new workbox.backgroundSync.Plugin('addToForm');
workbox.routing.registerRoute(
RegExp('MY_PATH'),
workbox.strategies.networkOnly({
plugins: [addToFormPlugin]
}),
'POST'
);
The code seems to works fine on my computer. However, once I run the app on the phone it takes ages to upload requests stored in IndexedDB. I know that it happens on the SYNC but it seems to take at least 5 minutes. This is not exactly what I need. I wonder if there is an option to access the IndexDB and send all the requests "manually" on click. Another way would be to check if the device is online. Here is how requests are stored:
If you need to force this, the cleanest approach would be to use the workbox.backgroundSync.Queue class (instead of workbox.backgroundSync.Plugin) directly.
The Plugin class takes care of setting up a fetchDidFail callback for you, so if you use the Queue class, you need to do that yourself:
const queue = new workbox.backgroundSync.Queue('addToForm');
workbox.routing.registerRoute(
RegExp('MY_PATH'),
workbox.strategies.networkOnly({
plugins: [{
fetchDidFail: async ({request}) => {
await queue.addRequest(request);
},
}],
}),
'POST'
);
You could then call queue.replayRequests() to trigger the replay, e.g., as a result of a message event:
self.addEventListener('message', (event) => {
if (event.data === 'replayRequests') {
queue.replayRequests();
}
});
But... that all being said, I think your best bet is just to let the browser "do its thing" and figure out when the right time is to replay the queued requests. That will end up being more battery-friendly for mobile devices.
If you're unhappy with the interval that the browser waits before firing a sync event, then the best course of action could be to open a bug against the browser—whether it's Chrome (as appears in your screenshot) or another browser.
I'm using Select2 builtin AJAX to load a tiny list of items. Select2 loads the entire list on first selection (good) but reloads the JSON feed every time the user tries to change his selection or type to filter items (and that means a new AJAX request for each typed letter!).
At A request is being triggered on every key stroke, can I delay this? we can read:
By default, Select2 will trigger a new AJAX request whenever the user
changes their search term. You can set a time limit for debouncing
requests using the ajax.delay option.
$('select').select2({
ajax: {
url: '/example/api',
delay: 250
}
});
This will tell Select2 to wait 250 milliseconds before sending the request out to your API.
... but it doesn't. Seriously. I've also tried the undocumented minimumInputLength property shown in examples but it doesn't seem to do anything.
Is it even possible to make Select2 fetch data only once?
The select2 ajax parameter sets off the ajax call every time the user changes her/his input. If you want to load your list only once, just load it via a normal ajax call when your page is loaded and set the result into the data attribute of your select2 like this:
var dataList;
$.ajax({
url : '/example/api',
success : function(data) {
dataList = data;
},
async : false
});
$('select').select2({
data: dataList
});
It is working for me. I tested it using a large delay: delay: 3000
The AJAX reqeust is indeed delayed 3 secs after the last keystroke.
It also works when deleting characters with the backspace key.
I'm using select2.full.js v4.0.3. Hope this helps.
Let me know if this solution would work for you:
1) bind an onChange action to your select element:
<select name="variable" onChange="loadyourlist($('option:selected',this).val());">
<option value="#">Select State</option>
<option value="1">State 1</option>
</select>
2) Make your request inside loadyourlist function, but check if it has been called before:
window.called = 0; //initial state
function loadyourlist(value){
if(!window.called){ //not called before
//make your ajax call
window.called = 1; //increment to avoid furter calls
}
}
From the index page, a user clicks a navigation link, the data attribute is passed via ajax, the data is retrieved from the server but the content is not being updated on the new page.
Been stuck for hours, really appreciate any help!
js
$('a.navLink').on('click', function() {
var cat = $(this).data("cat");
console.log(cat);
$.ajax({
url: 'scripts/categoryGet.php',
type: 'POST',
dataType: "json",
data: {'cat': cat},
success: function(data) {
var title = data[0][0],
description = data[0][1];
console.log(title);
$('#categoryTitle').html(title);
$('#categoryTitle').trigger("refresh");
$('#categoryDescription').html(description);
$('#categoryDescription').trigger("refresh");
}
});
});
Im getting the correct responses back on both console logs, so I know the works, but neither divs categoryTitle or categoryDescription are being updated. I've tried .trigger('refresh'), .trigger('updatelayout') but no luck!
This was not intended to be an answer (but I can't comment yet.. (weird SO rules)
You should specify in the question description that the above code IS working, that your problem occurs WHEN your playing back and forth on that page/code aka, using the JQM ajax navigation.
From what I understood in the above comment, you're probably "stacking" the ajax function every time you return to the page, thus getting weird results, if nothing at all.
Is your example code wrapped into something ? If not, (assuming you use JQM v1.4) you should consider wrapping it into $( 'body' ).on( 'pagecontainercreate', function( event, ui ) {... which I'm trying to figure out myself how to best play with..
Simple solution to prevent stacking the ajax definition would be to create/use a control var, here is a way to do so:
var navLinkCatchClick = {
loaded: false,
launchAjax: function(){
if ( !this.loaded ){
this.ajaxCall();
}
},
ajaxCall: function(){
// paste you example code here..
this.loaded = true;
}
}
navLinkCatchClick.launchAjax();
I have Entry model with url field, which contains link to external site.
In view I list these links, and now I'd like to start counting when someone clicks it, and keep this info in database. What's the best way of doing it?
You can easily use google analytics to track outbound links: http://support.google.com/analytics/bin/answer.py?hl=en&answer=1136920
If that is not an option you will need to add some javascript to your links make an ajax request to the server to increment the count before transferring the user to the new url. Something similar to this jquery code:
$('a').click(function(){
var stored_ulr = $(this).attr('href');
$.ajax({
url: #your server url to increment count,
data: #data you need to send,
success: function() { window.location = stored_url; },
});
return false;
});
The above code is just a general outline. You will have to fill in the blanks and make it work for your needs.
I'm developing a jquery mobile site that is only available to users that are logged in.
I have a function that checks a server for their logged in status:
function checkLogin() {
$(function () {
$.getJSON(root_url + 'manageUsers/checklogin/?callback=?', null,
function (data) {
if (data.logged == 'false') {
$("#index_Container").html("<h2>Login Required</h2></div><p>We've noticed you're not logged in, please login to use this app.</p><p><a href='login.html' data-role='button'>Click here to login</a></p>").trigger('create');
$.mobile.changePage('login.html');
} else {
$(".logged_in").text(data.username);
$(".logged_in").addClass('logout');
$(".header_div").trigger('create');
}
});
});
}
I can't seem to figure out how to implement this so everytime the index page is loaded and any other page loads this is fired prior to rendering anything else on the page. Currently, the page will load and show the HTML, then do $.mobile.changePage('login.html'):
EDIT: If anyone has any ideas on how to implement this in a better way I'd love to know, every page in the app requires the user to be logged in.
In order to have this function run every time you load anew page, you will need to bind it to the pagebeforeload event, and potentially cancel the user navigation if it does not validate the login.
$( document ).bind( "pagebeforeshow", function( event, data ){
event.preventDefault(); //prevents usual load of page
checkLogin(data);
});
You will have to make changes to checkLogin, notably because as the page does not exist yet, so you cannot make changes to the DOM. You can see an quick and dirty example in this fiddle, giving hints as to how do it considering the asynchronous nature of your call.