IE only anglure http request cache / MVC issue - angularjs

I have some code that loads a list from a MVC controller.
I load the data with
$scope.loadData = function () {
$scope.promise = myhttp = $http.get("forms");
myhttp.success(function (response) {
$scope.rows = response;
This works fine, the data loads and I can see the data on my html page.
But, if I reload with code, eg I just run $scope.loadData again, it fails in IE.
Works in Chrome, FF
Fails in IE and Spartan (Tested on non windows 10 same issue)
The headers look like
Cache-Control: private, s-maxage=0
The MVC controller has the authorise attribute hence the s-maxage=0, this prevents the proxy from caching.
I have tried
$scope.promise = myhttp = $http.get("forms");
When I fiddle, i dont see the request going to the server but the code does get fired.
If I nav to a new page and nav back it does reload fresh data as you would expect. It just when the reload is done with $http
Thanks
EDIT
Post works, eg
$scope.promise = myhttp = $http.post("forms");

Related

(Angular) Js embedding an MS Word doc using AJAX return data as the URL

[Update] there is a 50 point bonus, which I will up to 200 for a working fiddle
[Update] while I prefer an AngualrJs solution, I will also accept plain JS - just anything to get me over this impasse ... a GET call to my server returns a URL and I want to embed that document into my HTML
With reference to my previous question, #MaximShoustin 's answer seemed perfect, but I am having problems.
The URL in that solution there is hard coded, but I want to get mine by AJAX. When I do, the document is not embedded, but I see no error in the developer console.
I made this fiddle, where I added these lines
to the HTML
<iframe ng-src="{{cvUrlTrusted_2}}"></iframe>
and, to the controller
app.controller('Ctrl', function($scope, $sanitize, $sce, $http) {
added , $http
and
// new stuff follows
var url = 'http://fiddleapi.rf.gd/getDocuemntUrl.php';
/* The URL contains this code ...
<?php
echo('https://d9db56472fd41226d193-1e5e0d4b7948acaf6080b0dce0b35ed5.ssl.cf1.rackcdn.com/spectools/docs/wd-spectools-word-sample-04.doc');
?>
*/
$http.get(url)
.success(function(data, status, headers, config)
{
var cvTrustedUrl_2 = 'http://docs.google.com/gview?url=' + data.trim() + '&embedded=true';
$scope.cvTrustedUrl = $sce.trustAsResourceUrl(cvTrustedUrl_2);
})
.error(function(data, status, headers, config)
{
alert('Urk!');
});
If you invoke the API at http://fiddleapi.rf.gd/getDocuemntUrl.php you will see that it returns the same document URL as was hard coded in the solution.
Please, first check my code, lest I have made a mistake.
Long description, short question : how can I embed a document who's URL is returned from an AJAX API into an HTML document using AngularJS? Free free to fork the fiddle.
Your fiddle doesn't work because of cross domain problem: http://fiddleapi.rf.gd/getDocuemntUrl.php
So I loaded simple JSON file with content:
{
"val":"https://d9db56472fd41226d193-1e5e0d4b7948acaf6080b0dce0b35ed5.ssl.cf1.rackcdn.com/spectools/docs/wd-spectools-word-sample-04.doc"
}
and:
$http.get('data.json').then(function (resp){
var cvTrustedUrl_2 = 'http://docs.google.com/gview?url=' + resp.data.val + '&embedded=true';
$scope.cvUrlTrusted_2 = $sce.trustAsResourceUrl(cvTrustedUrl_2);
});
Demo Plunker
It works fine so the problem is in your http://fiddleapi.rf.gd/getDocuemntUrl.php because this URL doesn't work in Postman too. I get:
This site requires Javascript to work, please enable Javascript in your browser or use a browser with Javascript support
be sure you configured it well

Database values updated but not visible in the client side angular web application

I have working angularjs and HTML web application. The problem that I am facing is that it doesn't updates the data changed in the server. But if I run it with debugger it works fine and updates the data as expected.
For example: script file
$http.get('http://localhost:8080/api/database')
.then(function(objectList){
$scope.objectList = objectList.data;
});
html file
<tr ng-repeat="object in objectList">
now when I revisit the page after adding new object to the objectList using location.path() and routeProvider the I can't see the newly added item in the list while if I perform the same activity with the debugger of browser open then I can see the new object in the List. However the data is added to the database at server side successfully.
The best practice would be to have a someService.js file for all the API requests and you can use that service in your controller. Moreover, you can set the scope variable as an empty array globally and then after resolving the promise you can push the success.data into the scope variable and it should work like a charm.
This should be in your controller:
$scope.objectList = [];
var databasePromise = someservice.getDatabase();
databasePromise.then(function(success) {
$scope.objectList = success.data;
}, function(failure) {
console.log(failure);
});
Please share a plunker, if you are having a hard time fixing it.
FOund the Solution to above question.
//initialize get if not there
if (!$httpProvider.defaults.headers.get) {
$httpProvider.defaults.headers.get = {};
}
// Answer edited to include suggestions from comments
// because previous version of code introduced browser-related errors
//disable IE ajax request caching
$httpProvider.defaults.headers.get['If-Modified-Since'] = 'Mon, 26 Jul 1997 05:00:00 GMT';
// extra
$httpProvider.defaults.headers.get['Cache-Control'] = 'no-cache';
$httpProvider.defaults.headers.get['Pragma'] = 'no-cache';

$resource posts empty object in Internet Explorer

I have an issue with Internet Explorer 11 and $resource service in Angular 1.4.9. My code calls web service to post some object:
var FooServiceHandle = $resource('some/Address/');
var fooServiceHandle = new FooServiceHandle ();
fooServiceHandle.bar = someData;
fooServiceHandle.$save().then(function () { console.log('saved') });
Web service on the other hand is WCF REST.
[OperationContract]
[FaultContract(typeof(RegistrationNotAllowedFault))]
[WebInvoke(UriTemplate = "some/Address/", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped)]
string Foo(Bar bar);
When I use IE the argument of the Foo method in the web service is null (but service method is called). Just before the $save call fooServiceHandle.bar variable isn't undefined, but a proper object. My code works in Chrome 48 and Firefox 44.
UPDATE
Strange thing is that when I look at network tab of IE developer tools it shows proper request body (which is JSON). Moreover when I copy-paste that request body to SoapUI it executes correctly. HTTP method of IE request is ok (POST), also content type (application/json). First IE request has result 307 and later there goes another with 400.
UPDATE2
I can't see any major differences in request between Chrome and IE except one - in IE order of JSON keys is slightly different, however structure is all right.
UPDATE3
Exactly the same issue with $http service. In Chrome it works and WCF binds an object, in IE it doesn't and gets null argument in service method.
var req = {
method: 'POST',
url: 'some/Address/',
data: { bar: someData}
}
$http(req).then(function(){console.log('saved')}, function(){});
Cause of this issue is pretty unbelievable. Somehow Internet Explorer and WCF together cannot handle slash at the end of service method address. Removing backslash eliminates the problem:
UriTemplate = "some/Address/" => UriTemplate = "some/Address"
var FooServiceHandle = $resource('some/Address/'); => var FooServiceHandle = $resource('some/Address');
In both Chrome and Firefox backslash is not a problem, probably they trim it.

How do I use $httpBackend (e2e) without refreshing the page i.e without browser.get

I am using Protractor and ngMockE2E to mock api responses. It works fine if I use browser.get to navigate to the next page. The expected mock data is returned, however when I navigate to the next page using a click() on the search button, $httpBackend does not pick up the GET and live data is returned.
I need it to return mock data on a button click because the application starts a session when the application loads. Browser.get causes a page refresh so although the mock data gets returned, a new session is created also which is not what happens in a live environment.
Can $httpBackend invoke a whenGET after a button click?
I am using TypeScript to write the code and http-backend-proxy for the mock module which uses ngMockE2E under the hood:
//httpBackEndMocks.ts
var HttpBackend = require('http-backend-proxy');
var proxy = new HttpBackend(browser);
export class HttpBackendMocks {
/**
* Builds a mock module passing any number of the responses below
*/
buildMockModule = (funcs: Function[]) => {
if (Array.isArray(funcs)) {
for (var arrayIndex in funcs) {
funcs[arrayIndex];
}
}
/** Allow all other GET requests to pass through e.g. html pages */
proxy.onLoad.whenGET(/.*/).passThrough();
}
/**
* ...
*/
buildSimpleResponse() {
var response = require('../responses/simple-respsonse.json');
return proxy.onLoad.whenGET('the request url').respond(response);
}
otherResponse() {whenGET...}
otherResponse() {whenGET...}
....
I can then require:
//search.page.spec
var httpBackEndMocks: app.test.HttpBackendMocks = require('../httpBackEndMocks.js');
and load which ever responses I need:
beforeEach:
var responsesToLoad = [
httpBackEndMocks.buildSimpleResponse(),
httpBackEndMocks.otherResponse()
];
httpBackEndMocks.buildMockModule(responsesToLoad);
When I transition to the next page with this:
//search.object.page
browser.get('the url ...');
It Works. It returns the mock data BUT causes a page refresh initialising a new session.
When I transition to the next page with this:
this.submitButton.click(); //Code to cause button click omitted
It transitions to the next page without a page refresh, therefore in the same session but returns live data.
I figured out a solution myself for anyone who has a similar issue:
The mock module with any required responses should be added BEFORE protractor starts the application. This way whenever the initial browser.get(...) is called to load the homepage, all the whenGETs will be registered.
open(responsesToLoad: any[]): void {
this.buildMockModuleWithRequiredResponses(responsesToLoad);
browser.get('/home');
}

ajaxSubmit does not reload page after first request (in CakePHP)

I'm creating a CMS which has a page edit section. I'm trying to create a Preview function. It works fine on the first attempt, but if you then change some text and preview again, the preview is the old version. It also appears very quickly. It's as if the ajaxSubmit function doesn't bother reloading the page.
I tried to get round this by changing the url each time (by adding on a timestamp to the end), but this made no difference. I'm using jquery, cakePHP and fck editor.
Here's what I have:
<script type="text/javascript">
$('#page_modal').jqm();
$('#preview_btn').click(function(e){
// Get current page content from fck iframe
var oEditor = FCKeditorAPI.GetInstance('PageContent');
var newcontent = oEditor.GetData();
$('#PageContent').html(newcontent);
// Submit form via Ajax
var d=new Date();
var t=d.getTime();
var thisurl = '/admin/pages/preview/' + t.toString();
$('#ajaxForm').ajaxSubmit({
url: thisurl,
error: function(XMLHttpRequest, textStatus, errorThrown){
alert(textStatus);
},
success: function(responseText){
$('#page_modal').jqmShow().find('#page_modal_content').html(responseText);
}
});
e.preventDefault();
});
</script>
As I said, it works fine first time, but then on subsequent calls the content is not updated. Can anyone suggest anything?
Try marking the view (/admin/pages/preview) with no cache. In the actual view put:
<cake:nocache>
// your view content here
</cake:nocache>
It may be that the view is being cached by cake so it does not update with subsequent calls.
http://book.cakephp.org/view/347/Marking-Non-Cached-Content-in-Views

Resources