How to completely disable the cache in AngularJS - json

I use a form to submit values. When I click on the submit button, it calls edit().
Values are stored in the database (with php/mysql). Everything works fine so far.
I retrieve the values on the same partial view. On window.location.reload(); the page will refresh but the values are not instantly updated. After several refresh, it's
(When my DevTools is open, the cache is disable... so it's instantly updated)
Without the DevTools open, the cache works even if I put some function to disable the cache.
listingProjectApp.run(function($rootScope, $templateCache) {
$rootScope.$on('$viewContentLoaded', function() {
$templateCache.removeAll();
});
});
listingProjectApp.factory('EditCache', function($cacheFactory) {
return $cacheFactory('editCache', {
capacity: 1
});
});
listingControllers.controller('editProjectCtrl', ['$scope', '$http', '$routeParams', 'EditCache',
function ($scope, $http, $routeParams, EditCache) {
var result = EditCache.get('$http');
if( result ){
$scope.project = result;
console.log("Results from cache");
}
else {
$http({
url: "php/getProjectDetails.php",
method: "GET",
cache: false,
params: { 'id': $scope.projectId }
}).success(function(data) {
$scope.project = data;
EditCache.put('$http', data);
console.log("New results");
});
}
console.log(EditCache.info())
$scope.edit = function(project){
console.log(project);
$http({
url: "php/edit.php",
method: "POST",
data: project
}).success(function(id) {
EditCache.removeAll();
window.location.reload();
});
return false;
}
}]);

Looks like it's not the AngularJS cache's fault, but rather the browser's: for the browser, your XHR requests are simple HTTP GET requests, and all caching policies are applied to them. To avoid caching the partials, you'll have to either tweak your back-end to send appropriate headers to forbid caching, or use the old random suffix trick: add another dummy parameter to your params (like dummy: 'some-random-string'). This way, every GET request will be unique, and you'll not hit the cache.

Related

How can I send requests to JSON?

I'm coding a mobile application with ionic. I have to get a data (daily changing data) from a web page with JSON, but I want to get old data too. For example:
data.json?date=2016-11-10
data.json?data=2016-12-10
How can I send request to JSON?
To send data from PHP, once you get your data from the database, the array will apply json_encode($array); and to return you put return json_encode ($ array);
Try this!
var date = '2016-11-10';
$http({
method: 'GET',
url: data.php,
params: {date: date},
dataType: "json",
contentType: "application/json"
}).then(function(response) {
});
The question is confusing, so I'm not sure how to answer. If you are having trouble formatting a request to a REST service, you will need to find out how the service expects the date to be formatted in your field-value pair i.e:
date=2016/11/10 or date=20161110
If those don't work, this answer may help The "right" JSON date format
However, if you are actually wondering how to serialize a date in JSON, this link may help http://www.newtonsoft.com/json/help/html/datesinjson.htm
I prefer to use services for ajax requests.
Create a Service
//Service
(function() {
'use strict';
angular
.module('appName')
.factory('appAjaxSvc', appAjaxSvc);
appAjaxSvc.$inject = ['$http', '$log', '$q'];
/* #ngInject */
function appAjaxSvc($http, $log, $q) {
return {
getData:function (date){
//Create a promise using promise library
var deferred = $q.defer();
$http({
method: 'GET',
url:'/url?date='+date
}).
success(function(data, status, headers,config){
deferred.resolve(data);
}).
error(function(data, status, headers,config){
deferred.reject(status);
});
return deferred.promise;
},
};
}
})();
Then Use it in Controller
(function() {
angular
.module('appName')
.controller('appCtrl', appCtrl);
appCtrl.$inject = ['$scope', '$stateParams', 'appAjaxSvc'];
/* #ngInject */
function appCtrl($scope, $stateParams, appAjaxSvc) {
var vm = this;
vm.title = 'appCtrl';
activate();
////////////////
function activate() {
appAjaxSvc.getData(date).then(function(response) {
//do something
}, function(error) {
alert(error)
});
}
}
})();

DevExtreme datasource can't load Data Service data

I tried to accomplish the tutorial here, and when I used their data service, it worked just fine.
I modified the source to my data service (WCF Data Service v5.6, OData V2), and the list just shows the Loading sign and nothing happens.
The code should load any data type, it just has to be mapped accordingly. My service is availabe through the browser, I checked.
Here is the code:
DevExTestApp.home = function (params) {
var viewModel = {
dataSource: DevExpress.data.createDataSource({
load: function (loadOptions) {
if (loadOptions.refresh) {
try {
var deferred = new $.Deferred();
$.get("http://192.168.1.101/dataservice/dataservice.svc/People")
.done(function (result) {
var mapped = $.map(result, function (data) {
return {
name: data.Name
}
});
deferred.resolve(mapped);
});
}
catch (err) {
alert(err.message);
}
return deferred;
}
}
})
};
return viewModel;
}
What else should I set?
The try-catch block would not help is this case, because data loading is async. Instead, subscribe to the fail callback:
$.get(url)
.done(doneFunc)
.fail(failFunc);
Another common problem with accessing a web service from JavaScript is Same-Origin Policy. Your OData service have to support either CORS or JSONP. Refer to this discussion.

Cannot call a certain function twice in AngularJS

I have a bit of Angular code that I cannot seem to debug. The page on load renders all of my groups perfectly in the navigation drop down bar. When I go to click on one of the group, the messagesIndex function is called and all of the messages from that group will be displayed normally and at this point everything is working fine. The problem is when I go to click on another group, or even the same group, the messagesIndex function does not load a second time.
I have spent a lot of time trying to debug this issue to no avail, but I have narrowed down exactly where the problem is occurring, there just doesn't seem to be any issues there that I can find.
I replaced the contents of the messagesIndex function with just $scope.groupID, and outputted the result along with a random number. the groupID displayed along with the random number, and every time I clicked different groups different IDs and random numbers appeared, which means that the JADE/HTML is functioning properly and the function headers are golden.
I then took the original messagesIndex function and added $scope.random1 and scope.random2 with random numbers assigned to them to both the beginning and the end of the function, both before and after the HTTP request. When I called the function the first time, both random numbers generated and were outputted, though the http request is asynchronous all values were returned normally, hinting that the function called completely, unless there was an issue with the HTTP request dragging on after the success response? Then when I went to call it again by clicking another group. neither of the random numbers changed, showing that the function either did not call at all, or it stopped before executing the first line of code within it.
frankly speaking I am stumped. The code looks basically Identical to many working HTTP request, yet for some reason I cannot call it twice.
Below is the AngularJS code:
angular.module('angular-client').controller('GroupMeCtrl',
['$scope', '$http', '$templateCache', 'Auth', function($scope, $http, $templateCache) {
$scope.groupsIndex = function(){
$http({
method: 'GET',
url: 'https://api.groupme.com/v3/groups?token=' + token,
cache: $templateCache
}).
success(function(data, status) {
$scope.groupsIndex = data.response;
$scope.stat = status;
}).
error(function(data, status, headers, config) {
$scope.groupsIndex = data.response;
$scope.stat = status || "Request failed";
});
};
$scope.messagesIndex = function($groupID){
$http({
method: 'GET',
url: 'https://api.groupme.com/v3/groups/' + $groupID + '/messages?token=' + token,
cache: $templateCache
}).
success(function(data, status) {
$scope.messagesIndex = data;
$scope.stat = status;
}).
error(function(data, status) {
$scope.messagesIndex = data.response;
$scope.stat = status || "Request failed";
});
};
}]);
And below here is my JADE:
li.dropdown
a.dropdown-toggle(href='#', data-toggle='dropdown')
| Groups
b.caret
ul.dropdown-menu
li(ng-repeat="group in groupsIndex")
a(ng-click="messagesIndex(group.id)") {{group.name}}
.message-box(ng-repeat="message in messagesIndex.response.messages")
.avatar-container
img(src="{{message.avatar_url}}").avatar
.text
.user-name
{{message.name}}
span
{{message.text}}
You're overwriting the function with the data returned:
$scope.messagesIndex = function($groupID){
...
$scope.messagesIndex = data;
...
$scope.messagesIndex = data.response;
$scope.messagesIndex can't equal a function and the data you receive.

Service retrieves data from datastore but does not update ui

I have a service which retrieves data from the datastore (Web SQL). Afterwards, it stores the data in a AngularJS array. The problem is that this does not initiate changes to the UI.
Contrary, if after the retrieval of data from datastore, I call a web services using a $get method and append the results to the previous array, all data updates the UI.
Any suggestions? Is it possible that I fill the array before the Angular binds the variable?
Can I somehow delay the execution of the service?
Most of the code has been taken from the following example: http://vojtajina.github.io/WebApp-CodeLab/FinalProject/
In order for the UI to magically update, some changes must happen on properties of the $scope. For example, if retrieving some users from a rest resource, I might do something like this:
app.controller("UserCtrl", function($http) {
$http.get("users").success(function(data) {
$scope.users = data; // update $scope.users IN the callback
}
)
Though there is a better way to retrieve data before a template is loaded (via routes/ng-view):
app.config(function($routeProvider, userFactory) {
$routeProvider
.when("/users", {
templateUrl: "pages/user.html",
controller: "UserCtrl",
resolve: {
// users will be available on UserCtrl (inject it)
users: userFactory.getUsers() // returns a promise which must be resolved before $routeChangeSuccess
}
}
});
app.factory("userFactory", function($http, $q) {
var factory = {};
factory.getUsers = function() {
var delay = $q.defer(); // promise
$http.get("/users").success(function(data){
delay.resolve(data); // return an array of users as resolved object (parsed from JSON)
}).error(function() {
delay.reject("Unable to fetch users");
});
return delay.promise; // route will not succeed unless resolved
return factory;
});
app.controller("UserCtrl", function($http, users) { // resolved users injected
// nothing else needed, just use users it in your template - your good to go!
)
I have implemented both methods and the latter is far desirable for two reasons:
It doesn't load the page until the resource is resolved. This allows you to place a loading icon, etc, by attaching handlers on the $routeChangeStart and $routeChangeSuccess.
Furthermore, it plays better with 'enter' animations in that, all your items don't annoyingly play the enter animation every time the page is loaded (since $scope.users is pre populated as opposed to being updated in a callback once the page has loaded).
Assuming you're assigning the data to the array in the controller, set an $scope.$apply() after to have the UI update.
Ex:
$scope.portfolio = {};
$scope.getPortfolio = function() {
$.ajax({
url: 'http://website.com:1337/portfolio',
type:'GET',
success: function(data, textStatus, jqXHR) {
$scope.portfolio = data;
$scope.$apply();
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(errorThrown);
}
});
};

How to fetch a specific div id from an html file through ajax

I have two html files called index.html & video.html
video.html holds coding like:
<div id="video">
<iframe src="http://www.youtube.com/embed/tJFUqjsBGU4?html5=1" width=500 height=500></iframe>
</div>
I want the above mentioned code to be crawled from video.html page from index.html
I can't use any back-end coding like php or .net
Is there any way to do using Ajax?
Try this...
$.ajax({
url: 'video.html',
success: function(data) {
mitem=$(data).filter('#video');
$(selector).html(mitem); //then put the video element into an html selector that is on your page.
}
});
For sure,send an ajax call.
$.ajax({
url: 'video.html',
success: function(data) {
data=$(data).find('div#video');
//do something
}
});
Yep, this is a perfect use case for ajax. When you make the $.ajax() request to your video.html page, you can then treat the response similar to the way you'd treat the existing DOM.
For example, you'd start the request by specifying the URI in the the following way:
$.ajax({
url: 'video.html'
})
You want to make sure that request succeeds. Luckily jQuery will handle this for you with the .done callback:
$.ajax({
url: "video.html",
}).done(function ( data ) {});
Now it's just a matter of using your data object in a way similar to the way you'd use any other jQuery object. I'd recommend the .find() method.
$.ajax({
url: "video.html",
}).done(function ( data ) {
$(data).find('#video'));
}
});
Since you mentioned crawl, I assume there is the possibility of multiple pages. The following loads pages from an array of urls, and stores the successful loads into results. It decrements remainingUrls (which could be useful for updating a progressbar) on each load (complete is called after success or error), and can call a method after all pages have been processed (!remainingUrls).
If this is overkill, just use the $.ajax part and replace myUrls[i] with video.html. I sepecify the type only because I ran into a case where another script changed the default type of ajax to POST. If you're loading dynamic pages like php or aspx, then the cache property might also be helpful if you're going to call this multiple times per session.
var myUrls = ['video1.html', 'video2.html', 'fail.html'],
results = [],
remainingUrls;
$(document).ready(function () {
remainingUrls = myUrls.length;
for (var i = 0, il = myUrls.length; i < il; i++) {
$.ajax({
url: myUrls[i],
type: 'get', // somebody might override ajax defaults
cache: 'false', // only if you're getting dynamic pages
success: function (data) {
console.log('success');
results.push(data);
},
error: function () {
console.log('fail');
},
complete: function() {
remainingUrls--;
if (!remainingUrls) {
// handle completed crawl
console.log('done');
}
}
});
}
});
not tested, but should be something similair to this: https://stackoverflow.com/a/3535356/1059828
var xhr= new XMLHttpRequest();
xhr.open('GET', 'index.html', true);
xhr.onreadystatechange= function() {
if (this.readyState!==4) return;
if (this.status!==200) return; // or whatever error handling you want
document.getElementsByTagName('html').innerHTML= this.responseText;
};
xhr.send();