Not able to get image as json response using angularJS? - angularjs

I am getting image in json response form restful api and I have to use that image in html using angularjs.
I dont know how can I use that image using angularJs
If I am trying like that "http:/api/image/id" where id is "userID". But when I write the code in angularjs I didnt get any response.I tried to debug code by using breakpoints and but it didn't go inside the function
JS Code
QAApp.controller('imgCtrl', function ($scope, $http) {
$scope.image = function (id) {
var request = $http({
method: 'GET',
url: server + 'api/image/' + id,
});
request.success(function(data, status, headers, config) {
console.log(data);
});
}
});
HTML Code
<div class="artst-pic pull-left" ng-controller="imgCtrl">
<img ng-show = "{{image(q.userID)}}" alt="" class="img-responsive" />K
</div>
Please tell me how can I use this.

From what I understand, the API directly sends you the image, not any JSON..
Then just display it like you would display any image (you don't need ajax):
JS
$scope.image = function (id) {
return server + 'api/image/' + id;
};
HTML
<img ng-src="{{image(q.userID)}}"/>

Javascript
QAApp.controller('imgCtrl', function ($scope, $http) {
$scope.image = function (id) {
$http({
method: 'GET',
url: server + 'api/image/' + id,
}).then(function(data){
$scope.imageUrl= data; // if you sure what data is you URL
})
}
});
HTML
<div class="artst-pic pull-left" ng-controller="imgCtrl">
<img ng-src="{{imageUrl}}" ng-init="image(q.userID)" alt="" class="img-responsive" />K
</div>

The Apache Roller source code has an example of using angular.js to bring in an image source: http://svn.apache.org/viewvc/roller/trunk/app/src/main/webapp/WEB-INF/jsps/editor/ThemeEdit.jsp?annotate=1621546 (line 126, with the JavaScript at the bottom of the file).

Related

How to make a download button with the AngularJS $http service

Is it possible to trigger a download via a button and using AngularJS $http service in the background to provide the file?
I want to have a simple button, which starts a file download without opening a new window. Furthermore I have to set the Authorization inside of the header.
So far I did this:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
$scope.startDownload = function() {
var auth = ""; //username + password
$http.defaults.headers.common['Authorization'] = auth;
//this will return a file
$http({
method: 'GET',
url: 'https://upload.wikimedia.org/wikipedia/commons/1/1c/FuBK_testcard_vectorized.svg?download'/*,
headers: {
'Authorization': 'Basic efhjwefjfbweikabfkwhfb'
}*/
}).then(function(){
//????
});
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<button type="button" ng-click="startDownload()">Download</button>
</div>
change this :
ng-click="startDownload()"
After reading a ton of questions regarding similar problems, it emphasizes that it is not possible to save a file on the users disk, which comes from an AJAX request.
See this question on Stackoverflow.

getting type=" " while uploading csv file in angularjs

I am uploading a csv file using lf-ng-md-file-input(angularjs) but while uploading it is not recognizing the type of csv file whereas it is recognizing the type of images and pdf files. I am not getting why this is happening. Can anyone tell me why it is not recognizing the type of csv file as 'text/csv'. Any help will be appreciated. Thank you`
This is my HTML code. I am using lf-ng-md-file-input for uploading file & a submit button which calls a method in controller.
<div>
<div>
<div class="marginAll16">
<lf-ng-md-file-input lf-files='files' lf-mimetype='text/csv' accept='.csv' multiple progress drag preview></lf-ng-md-file-input>
</div>
</div>
<div>
<div>
<md-button type="button" class="btn submitButton btn-lg" ng-click="uploadFiles()">Submit</md-button>
</div>
</div>
My Controller-
This is controller which is calling a service for posting files to the server.
$scope.uploadFiles = function(){
angular.forEach($scope.files,function(obj){
uploadService.uploadFiles(obj,$scope.userId,$scope.auth_token).success(function(data, status, headers, config) {
console.log(data);
}).error(function(data, status, headers, config) {
});
});
};
My Service -
Here in service I am creating a formdata object & appending "uploadedFile.lfFile" to it. uploadedFile.lfFile is a file object which contains all the file information but in this file object it is displaying type:"".
pkService.factory('uploadService',['$http',function($http)
{
return{
uploadFiles : function(uploadedFile, userId, authToken){
var datafile = new FormData();
datafile.append('file',uploadedFile.lfFile);
return $http.post(hostname + 'users/upload_data_files.json?user_id=' + userId + '&auth_token=' + authToken,datafile, {
transformRequest: function(data) { return data; },
headers: {'Content-Type': undefined,
enctype:'multipart/form-data'}
});
}
};
}]);
So, my question is why it is getting an empty type, where i am going wrong?
Your markup...
<lf-ng-md-file-input lf-files='files' lf-mimetype='text/csv' accept='.csv' multiple progress drag preview></lf-ng-md-file-input>
Should look more like below.
<lf-ng-md-file-input lf-files="files" accept="text/csv" multiple progress drag preview></lf-ng-md-file-input>

Render remote PNG image in AngularJS

I am developing an AngularJS application which displays a PNG image retrieved from a server.
If I put the URL (see below) in the browser I can see the image just fine. However, if I want to retrieve such image from my Angular application I cannot manage to display it (although I do receive the data!).
The JS code is the following:
$scope.receivedImage = null;
var url = 'https://subdomain.mydomain.uk/img?latitude=55.57&longitude=-5.16&extent=2000';
$http(
{
method: 'GET',
url: url,
headers: {
Accept: 'image/png'
}
}
).then(
function successCallback(response) {
var data = response.data;
$scope.receivedImage = data;
},
function errorCallback(response) {
console.error(response);
}
);
The problem is that I cannot see the image that is retrieved. To understand better the situation I put in the HTML page the following code:
<div ng-show="receivedImage">
<pre>{{receivedImage}}</pre>
<img data-ng-src="{{receivedImage}}" />
<img data-ng-src="data:image/png;{{receivedImage}}" />
</div>
The '' shows something like
�PNG IHDR�R9�%IDATx��̱ ������ �2��'��j�Z�V��w����LxIEND�B`�
The first '' does not show anything.
The second '' shows an image icon and throws in console an error:
GET
data:image/png;%EF%BF%BDPNG%1A%00%00%00IHDR%00%00%00%1E%00%00%00%1E%08%02%0…%BD%EF%BF%BD%EF%BF%BD%EF%BF%BDL%0E%17x%00%00%00%00IEND%EF%BF%BDB`%EF%BF%BD
net::ERR_INVALID_URL
How can I render this image correctly?
Try setting the ng-src attribute to a variable that is the url.
$scope.url = 'https://subdomain.mydomain.uk/img?latitude=55.57&longitude=-5.16&extent=2000';
and in the markup
<img ng-src="{{url}}" />
If the url is unprotected then the approach from Anthony helps a lot. For my use-case where the URL was protected i had to go with the below approach. In this case i had to inject the authentication headers by overriding angular's http authentication interceptors for accessing the protected URL.
// http call inside a service under a function named getImage()
$http(
{
method: 'GET',
url: 'YOUR_PROTECTED_RESOURCE_URL',
// This is required for getting your data as buffer array
{
responseType: 'arraybuffer'
}
}
).then(
function successCallback(response) {
return response;
},
function errorCallback(response) {
console.error(response);
}
);
Inside your controller or directive the data that comes from the above call has to be handled like so:
// Function to get the image from the server
var handleImage = function(){
MyHttpService.getImage()
.then(function(response){
// Can be used within ng-src fro displaying image
$scope.receivedImage = 'data:image/png;base64,'+_arrayBufferToBase64(response);
}, function(error){
console.error(error);
});
};
// Convert the buffer to base64
var _arrayBufferToBase64 = function( buffer ) {
var binary = '';
var bytes = new Uint8Array( buffer );
var len = bytes.byteLength;
console.log(len);
for (var i = 0; i < len; i++) {
binary += String.fromCharCode( bytes[ i ] );
}
return window.btoa( binary );
};
Hope this helps someone who is trying to access the resource from a protected resource URI.

angularjs: $http is cached

So I have a service like that:
.service("checkSystemStatus", ["$http", "statusUrl", function($http, statusUrl){
return $http({method: "GET", url: statusUrl, cache: false});
}])
With this markup:
<li ng-mouseenter="checkStatus()">
<i class="fa fa-info-circle"></i>
<div class="info-container">
<h4>System Info</h4>
<table class="system-info">
<tr ng-repeat="(key, value) in systemInfo">
<td>{{key}}</td>
<td>{{value}}</td>
</tr>
</table>
</div>
</li>
and this function:
$scope.checkStatus = function(){
$scope.systemInfo = {};
checkSystemStatus.then(function(success){
$scope.systemInfo.running = success.data.jobs_running;
$scope.systemInfo.queued = success.data.jobs_queued;
$scope.systemInfo.cached = success.data.jobs_cached;
$scope.systemInfo.active_threads = success.data.threads_active;
$scope.systemInfo.server_address = success.data.server_address;
$scope.systemInfo.server_port = success.data.server_port;
console.log($scope.systemInfo);
})
}
The issue is I always get the same values for systemInfo, anytime I hover the info icon, I can't see any XHR requrest in the console except for the first one, that happens on loading the page and NOT when I hover the mouse on the tag.
The only way to solve this so far has been adding a parameter at the end of the url like
?time=unixtime to get a new url each time, but what about a cleaner solution without trailing params? Is it possible?
Well, it not only depends on the "AngularJS"-Cache but also on the Browser and Server cache settings. Check what kind of Cache-Headers the server in his responses sends to the Client. Adding a "timestamp" parameter to the REST-URL is one trick to avoid browser based caching - yes.
But in general: That's the way a client-server communication is intended to be. I would suspect that the Server sends some Vary, ETag, Cache-Expire etc. headers which will match.
Try to add these http headers into the server's response:
Cache-Control:no-cache, no-store, must-revalidate
Expires:-1
Pragma:no-cache
Try like this
.service("checkSystemStatus", ["$http", "statusUrl", '$q', function($http, statusUrl, $q){
this.GetData = function(){
$http.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
return $http({
method: "GET",
url: statusUrl,
cache: false //no need to use this, caching is false by default
}).
then( function(response){
if (response.data) {
return response.data;
}
else
return $q.reject('Request failed');
});
}
}]);
Controller part
$scope.checkStatus = function(){
$scope.systemInfo = {};
checkSystemStatus.GetData().then(function(data){
$scope.systemInfo.running = data.jobs_running;
$scope.systemInfo.queued = data.jobs_queued;
$scope.systemInfo.cached = data.jobs_cached;
$scope.systemInfo.active_threads = data.threads_active;
$scope.systemInfo.server_address = data.server_address;
$scope.systemInfo.server_port = data.server_port;
console.log($scope.systemInfo);
})
}
As other answers tell you: the browser may choose to cache the response if the appropriate response headers from the server is not set. Set the response headers in MajoBs answer.
If you are unable to update the response headers from the server you could make sure that the url is unique for every request. You can do this by adding a timestamp to the url:
.service("checkSystemStatus", ["$http", "statusUrl", function($http, statusUrl){
statusUrl = statusUrl + '?' + Date.now();
return $http({method: "GET", url: statusUrl, cache: false});
}])

change Content-type to "application/json" POST method, RESTful API

I am new at AngularJS and I needed your help.
All I need just need is to POST my json to the API and recieve the proper response.
Here's my JSON where i don't know where to code this.
JSON
{
"userId" :"testAgent2",
"token" :"testAgent2",
"terminalInfo":"test2",
"forceLogin" :"false"
}
NOT SURE IF I'm doing this right.
CONTROLLER.JS
function UserLoginCtrl($scope, UserLoginResource) {
//Save a new userLogin
$scope.loginUser = function() {
var loggedin = false;
var uUsername = $scope.userUsername;
var uPassword = $scope.userPassword;
var uforcelogin = 'true';
UserLoginResource.save();
}
}
SERVICES.JS
angular.module('UserLoginModule', ['ngResource'])
.factory('UserLoginResource', function($resource, $http) {
$http.defaults.useXDomain = true;
delete $http.defaults.headers.common['X-Requested-With'];
$http.defaults.headers.post["Content-Type"] = "application/json"; //NOT WORKING
return $resource('http://123.123.123.123\\:1234/SOME/LOCATION/THERE', {}, {
save: {
method:'POST',
headers: [{'Content-Type': 'application/json'}]
} //NOT WORKING EITHER
});
});
INDEX.HTML
<html ng-app>
<head>
<script src="js/lib/angular/angular.js"></script>
<script src="js/lib/angular/angular-resource.js"></script>
</head>
<body ng-controller="UserLoginCtrl">
<form class="form-horizontal" name="form-horizontal" ng-submit="loginUser();">
<div class="button-login">
<!-- start: button-login -->
<button class="btn btn-primary" type="submit">Login</button>
</div>
</form>
</body>
</html>
I kept on getting a response like Unsupported Media Type. I don't know, what else to do.
Assuming you are able to use one of the more recent "unstable" releases, the correct syntax to change the header is.
app.factory('BarService', function ($resource) {
var BarService = $resource('/foo/api/bars/:id', {}, {
'delete': {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
}
}
});
return BarService;
});
I find the $resource service is a tremendously powerful tool for building applications and has matured to a point that you do not need to fall back to $http as much. Plus its active record like patterns are damn convenient.
Posting a JSON object is quite easy in Angular. All you need to do is the following:
Create a Javascript Object
I'll use your exact properties from your code.
var postObject = new Object();
postObject.userId = "testAgent2";
postObject.token = "testAgent2";
postObject.terminalInfo = "test2";
postObject.forceLogin = "false";
Post the object to the API
To post an object to an API you merely need a simple $http.post function. See below:
$http.post("/path/to/api/", postObject).success(function(data){
//Callback function here.
//"data" is the response from the server.
});
Since JSON is the default method of posting to an API, there's no need to reset that. See this link on $http shortcuts for more information.
With regards to your code specifically, try changing your save method to include this simple post method.
The right way to set 'Content-Type': 'application/json' is setting a transformRequest function for the save action.
angular.module('NoteWrangler')
.factory('NoteNgResource', function NoteNgResourceFactory($resource) {
// https://docs.angularjs.org/api/ngResource/service/$resource
return $resource("./php/notes/:id", {}, {
save : { // redefine save action defaults
method : 'POST',
url : "./php/notes", // I dont want the id in the url
transformRequest: function(data, headers){
console.log(headers);
headers = angular.extend({}, headers, {'Content-Type': 'application/json'});
console.log(headers);
console.log(data);
console.log(angular.toJson(data));
return angular.toJson(data); // this will go in the body request
}
}
});
});
It seems there isn't a method to clear query parameters, the request will have both...

Resources