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

[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

Related

location.path() not redirecting to page

In node this is how I define my details route (render as jade and send).
app.get('/details', function(req, res){
jade.renderFile('details.jade', function(err, html){
if(err){
console.log(err);
}
res.send(html);
});
});
In jade with 'blah' is clicked then calls navigateToPath function with params.
a(ng-click="navigateToPath(date_obj_key, part)") blah
In angular, this function should go to this path. The url path changes in the browser but it does not REDIRECT to the page. Help (yes I am injecting the location service)
$scope.navigateToPath = function(date, part){
var path = '/details?date='+date+'&part_type='+part;
$location.path('/details').replace(); //also tried $location.url(path)
$scope.apply(); //also tried $scope.$apply and $rootScope.$apply as func
console.log($location.path());
}
I am using Fire Fox developer tools(F12) and put a break point on where I used $window.location in my project and looked at the values in $window.location and this what it shows:
It seems like this would work. for both a location in the same folder or sub-folder as well as going to a completely different web site.
$window.location = $window.location.origin + path
or
$window.location = <whatever website you want to go to>
In my case I was just using the $window.location to call a rest service to download a file that the user selected from a ui-grid while still staying on the same page. and this may have worked for me because my scenario is a bit different then what yours is I think. so all I had to do was
$window.location = "../../services" + "<path to my rest service>" + $scope.shortCode + "/" + $scope.wireInstSelectedRow.entity.fileName;
#shapiro I am not sure why this does not work
$location.path('/details').replace();
I tried the same thing originally in my project and based on the documentation: https://docs.angularjs.org/api/ng/service/$location It seems like that would work and what its supposed to be used for but what I noticed is it would put a '#' character in the url before it put the path I wanted it to take which was preventing it from going to that page. Anyhow for me it seems like as long as you are going to an html page that is in the same folder or sub-folder just doing
$window.location = <the path you want to go to>;
is a good solution... at least it did the trick for me. Hope this helps.

How works simple table load with AngularJS?

I'm trying to learn AngularJS starting with that example: http://jsfiddle.net/mjaric/pJ5BR/
but when I tried to download in localhost, not works. I think that is a URL problem in /echo/json':
$scope.loadPeople = function() {
var httpRequest = $http({
method: 'POST',
url: '/echo/json/',
data: mockDataForThisTest
}).success(function(data, status) {
$scope.people = data;
});
};
But I don't know how to solve it. Any idea or hint?
My finally idea is load json from a search petition. It's possible that 'data' will be charged from web or online.
The url: '/echo/json/' is a feature of JsFiddle. If you look at the tabs to the left, in Ajax Requests you can see the usage. It probably won't work with this url in localhost.
You need to create a web project, where you can send your request. You could send some search parameters from client side, then filter the data with those parameters in the server and then return the filtered data to show.
The following article will give you some good ideas
http://tutorials.jenkov.com/angularjs/ajax.html
This link provides a hands on example by a really good tutor.
http://weblogs.asp.net/dwahlin/learning-angularjs-by-example-the-customer-manager-application

No 'Access-Control-Allow-Origin' header is present on the requested resource- AngularJS

XMLHttpRequest cannot load http://mywebservice. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access.
I get this error when I try to run my web-service from inside my code. I tried finding about it and tried many solutions which were suggested which I found on net. Pasting the code below.
<form name="LoginForm" ng-controller="LoginCtrl" ng-submit="init(username,password,country)">
<label>Country</label><input type="text" ng-model="country"/><br/><br/>
<label>UserName</label><input type="text" ng-model="username" /></br></br>
<label>Password</label><input type="password" ng-model="password">
</br>
<button type="submit" >Login</button>
</form>
And controller form the corresponding js is:
app.controller('LoginController', ['$http', '$scope', function ($scope, $http) {
$scope.login = function (credentials) {
$http.get('http://mywebservice').success(function ( data ) {
alert(data);
});
}
}]);
The web-service works fine when I hit it from URL bar. How to resolve the problem? Kindly help!
The Chrome Webstore has an extension that adds the 'Access-Control-Allow-Origin' header for you when there is an asynchronous call in the page that tries to access a different host than yours.
The name of the extension is: "Allow-Control-Allow-Origin: *" and this is the link: https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi
On the client side you can enable cors requests in AngularJS via
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]);
However if this still returns an error, this would imply that the server that you are making the request has to allow CORS request and has to be configured for that.
This is a CORS issue. There are some settings you can change in angular - these are the ones I typically set in the Angular .config method (not all are related to CORS):
$httpProvider.defaults.useXDomain = true;
$httpProvider.defaults.withCredentials = true;
delete $httpProvider.defaults.headers.common["X-Requested-With"];
$httpProvider.defaults.headers.common["Accept"] = "application/json";
$httpProvider.defaults.headers.common["Content-Type"] = "application/json";
You also need to configure your webservice - the details of this will depend on the server side language you are using. If you use a network monitoring tool you will see it sends an OPTIONS request initially. Your server needs to respond appropriately to allow the CORS request.
The reason it works in your brower is because it isn't make a cross-origin request - whereas your Angular code is.
I have a solution below and its works for me:
app.controller('LoginController', ['$http', '$scope', function ($scope, $http) {
$scope.login = function (credentials) {
$http({
method: 'jsonp',
url: 'http://mywebservice',
params: {
format: 'jsonp',
callback: 'JSON_CALLBACK'
}
}).then(function (response) {
alert(response.data);
});
}
}]);
in 'http://mywebservice' there must be need a callback parameter which return JSON_CALLBACK with data.
There is a sample example below which works perfect
$scope.url = "https://angularjs.org/greet.php";
$http({
method: 'jsonp',
url: $scope.url,
params: {
format: 'jsonp',
name: 'Super Hero',
callback: 'JSON_CALLBACK'
}
}).then(function (response) {
alert(response.data);
});
example output:
{"name":"Super Hero","salutation":"Apa khabar","greeting":"Apa khabar Super Hero!"}
I added this and it worked fine for me.
web.api
config.EnableCors();
Then you will call the model using cors:
In a controller you will add at the top for global scope or on each class. It's up to you.
[EnableCorsAttribute("http://localhost:51003/", "*", "*")]
Also, when your pushing this data to Angular it wants to see the .cshtml file being called as well, or it will push the data but not populate your view.
(function () {
"use strict";
angular.module('common.services',
['ngResource'])
.constant('appSettings',
{
serverPath: "http://localhost:51003/About"
});
}());
//Replace URL with the appropriate path from production server.
I hope this helps anyone out, it took me a while to understand Entity Framework, and why CORS is so useful.
In my case, I was trying to hit a WebAPI service on localhost from inside an MVC app that used a lot of Angular code. My WebAPI service worked fine with Fiddler via http://localhost/myservice. Once I took a moment to configure the MVC app to use IIS instead of IIS Express (a part of Visual Studio), it worked fine, without adding any CORS-related configuration to either area.
I got
No 'Access-Control-Allow-Origin' header is present
and the problem was with the URL I was providing. I was providing the URL without a route, e.g., https://misty-valley-1234.herokuapp.com/.
When I added a path it worked, e.g.,
https://misty-valley-1234.herokuapp.com/messages. With GET requests it worked either way but with POST responses it only worked with the added path.
Use this extension for chrome.
Allows to you request any site with ajax from any source. Adds to response 'Allow-Control-Allow-Origin: *' header
https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi/related
Replace get with jsonp:
$http.jsonp('http://mywebservice').success(function ( data ) {
alert(data);
});
}
It is a problem on the server side. You have to add your client address to your server exposed API. If you are using Spring frame work you can annotate #CrossOrgin from org.springframework.web.bind.annotation.CrossOrigin;
Eg : #CrossOrigin(origins = "http://localhost:8080")
If you are using chrome: try open chrome with the args to disable web security like you see here:
Disable same origin policy in Chrome
This is how it worked for me. For Windows users testing with Bracket and AngularJS
1) Go to your desktop
2) Right click on your desktop and look for "NEW" in the popup drop down dialog box and it will expand
3) Choose Shortcut
4) A dialog box will open
5) Click on Browse and look for Google Chrome.
6) Click Ok->Next->Finish and it will create the google shortcut on your desktop
7) Now Right Click on the Google Chrome icon you just created
8) Click properties
9) Enter this in the target path
"C:\Program Files\Google\Chrome\Application\chrome.exe" --args --disable-web-security
10) Save it
11) Double click on your newly created chrome shortcut and past your link in the address bar and it will work.

angularjs custom REST action and error handling

I'm having some trouble with error handling in a little angularjs application. I'm interacting with a Flask backend and a Postgres DB.
I have a factory service
appointServices.factory('Appointments', ['$resource', function($resource){
return $resource(someUrl, {}, {
query: { ... }
,
create: {
method: 'POST'
,url: 'http://somedomain:port/new/:name/:start/:end/:treatment'
,params: { start: '#start', end: '#end', name: '#name', treatment: '#treatment' }
,isArray:false
}
});
}
]);
Inside a controller I'm making the following call
Appointments.create($scope.appointment, function(value, responseHeaders) {
// success handler
console.debug('success: ', JSON.stringify(value));
}, function(httpResponse) {
// error handler
console.debug('error: ', JSON.stringify(httpResponse));
});
Here $scope.appointment contains the relevant parameters for the create action.
Now, in the backend I'm able to catch DB errors involving constraints and I'm trying to return an error code with a 'meaningful' message. So I have a python method
def create(name, start, end, treatment):
try:
...
transaction_status = 'ok'
code = 200
except IntegrityError as e:
...
transaction_status = 'IntegrityError'
code = 500
finally:
...
return make_response(transaction_status, code)
Everything works fine, I'm able to talk to the backend, create new data and insert this in the DB. As I said, any violation of the constraints is detected and the backend responds
curl -X POST "http://somedomain:port/new/foo/bar/baz/qux" -v
...
< HTTP/1.0 500 INTERNAL SERVER ERROR
...
IntegrityError
So, the problem is, no matter whether the action create was successful or not, the intended error handler specified inside the controller is always fired. Moreover, I always end up with a status code 404 in the httpResponse. Firebug shows correctly the code 500 as above, though.
Anybody has any idea of why I'm getting this behavior?
Any suggestions on how to improve the error handling mechanism are also welcome.
Thx in advance.
P.S. Following the documentation on $resource I have also tried variations on the factory service call, e.g.
Appointments.create({}, $scope.appointment, successCallback, errorCallback);
Appointments.create($scope.appointment, {}, successCallback, errorCallback);
with the same results.
Update:
Forgot to mention the important fact that I'm interacting with the backend via CORS requests. The POST request in create above is having place with the OPTIONS method instead. As I mentioned everything is working correctly except for the error response.
Under further investigation, I tried to isolate the factory service, in case I did something wrong, and I also tried the approach shown in the credit card example ($resource docs), but with no positive result.
However, I came up with two workarounds. Firstly, I was able to create a plain JQuery POST request, as in the example shown in the docs. This time, the request is not replaced by OPTIONS and I got the error code correctly.
I also managed to connect to the backend with the low-level $http service as follows:
var urlBase = 'http://somedomain:port/new/:name/:start/:end/:treatment';
var url = urlBase.replace(/:name/g, $scope.appointment.name);
url = url.replace(/:start/g, $scope.appointment.start);
url = url.replace(/:end/g, $scope.appointment.end);
url = url.replace(/:treatment/g, $scope.appointment.treatment);
// force method to be POST
var futureResponse = $http({ method: 'POST', url: url });
futureResponse.success(function (data, status, headers, config) {
console.debug('success: ', JSON.stringify(data));
});
futureResponse.error(function (data, status, headers, config) {
console.group('Error');
console.debug(JSON.stringify(status));
console.debug(JSON.stringify(data));
console.groupEnd();
});
This time, as in the case of JQuery, the request is done effectively with POST and error codes are correctly received.
Notice also that I'm not calling $http.post but I set the method to POST as part of the object parameter to $http, otherwise the connection takes places with OPTIONS as before.
Still trying to figure out what is happening with $resource.

Angular $httpProvider transformResponse data contains local HTML DOM elements?

When I instantiate the following code in an AngularJS app, I get weird data in the transformResponse function (bottom of code). I'm not calling the $resource function from any controller, just loading the script in a browser. The data variable (see code) contains the HTML of the current partial, when loading the app.
This seems odd. Is this the way it's supposed to be?
var buddyServices = angular
.module('buddyServices', ['ng','ngResource'])
.factory('Buddy',
function ($resource) { console.log('resource');
return $resource('http://webservice.buddyplatform.com/v1/:service',
{service:'', BuddyApplicationName: 'xxx',
BuddyApplicationPassword: 'yyy'}
);
}
)
.config(function($httpProvider){
delete $httpProvider.defaults.headers.common['X-Requested-With'];
$httpProvider.defaults.transformResponse = function(data) {
console.log(data);
return 'TEST: '+data;
};
});
=== EDIT ===
It just daunted on me: $httpProvider handles all http requests, so a page load is one of those. I'm guessing a bit now, but it seems probable. So, the question then becomes: Is there an "easy" way to constrain the data in the code above to only those requests performed by my service?
transformResponse takes another parameter headersGetter. You can use this to get the headers send with the response. Look for Content-Type header header. It should contain application/json

Resources