After reseaches and tests, I still can't show an image form ReST API on my Angular App. I have images available on my ReST web service, why do I use a ReST service? Because in order to access you need to be authenticated (I use oAuth 2 protocol). When I use POSTMan (ReST client very usefull) everything works great, the image is displayed without doing nothing. But when I try to display it with Angular after a $http it doesn't work.
Here are the headers received form the service :
Content-Length → 51756
Content-Type → image/jpeg; charset=binary
Server → Apache/2.4.9 (Win64) PHP/5.5.12
X-Powered-By → PHP/5.5.12
Here is my Angular code :
var data64 = $base64.encode(unescape(encodeURIComponent(data)));
scope.src = 'data:image/jpeg;charset=binary;base64,' + data64;
and my HTML :
<img ng-src="{{src}}" border="0" />
For information I use angular-base64 (https://github.com/ninjatronic/angular-base64) for the encodage. Without "unescape" and "encodeURIComponent" I have an error, I've tried to remove white spaces but it still doesn't work.
Thank you :)
Seems that this will not work since you tell the browser that the image data is base64 encoded, but you also transformed it with unescape and encodeURIComponent.
Why don't you fetch your image data into a binary data structure (requires a modern browser), instead of into a string:
$http.get(req, {responseType: "arraybuffer"}).
success(function(data) {
$scope.src = 'data:image/jpeg;base64,' + _arrayBufferToBase64(data);
});
_arrayBufferToBase64 is defined here.
A different approach would be to install a request interceptor, recognize the image url and add the oauth headers for this case.
I tryed this way in angular 8+ and works fine:
imageToShow: any;
createImageFromBlob(image: Blob) {
let reader = new FileReader();
reader.addEventListener("load", () => {
this.imageToShow = reader.result;
}, false);
if (image) {
reader.readAsDataURL(image);
}
}
and also call it like this:
getImageFromService() {
this.api.getImage(key).subscribe(data => {
this.createImageFromBlob(data);
}, error => {
console.log(error);
});
}
Related
I am using Django Rest Framework and React.js for my application. As part of the application I generate pdf in the backend and then send them to the frontend to be displayed. This functionality is working, if not for the fact that the font in my pdf at the front-end looks different.
In my backend I am using reportlab to generate the pdfs, using buffer = io.BytesIO() as object of reportlab.pdfgen canvas.
Then in my view, I send it via FileResponse. The font family I use id 'Roboto'.
In my frontend I then call the API via Axios and open the pdf with the following code.
const config = {
headers: {
Authorization: `Bearer ${access_token}`
}
}
const { data } = await axios.get(
`/api/my/url/`,
config
)
const file = new Blob([data], { type: "application/pdf" });
//Build a URL from the file
const fileURL = URL.createObjectURL(file);
//Open the URL on new Window
const pdfWindow = window.open();
pdfWindow.location.href = fileURL;
This correctly opens my pdf in a new window.
However, the font of my pdf is changed, the characters look a bit different (and utf-8 symbols are completely changed with other symbols).
When I test my API with Postman, the downloaded pdf looks exactly as it should, so I believe the problem is in the frontend.
I'm not sure what is the cause of the problem, so I would really appreciate help!
I'm new to React js And I using Yii2 as my backend..! When I Send a API request to yii2 ,It Returns me the 500 Error.I don't know,Where I made a mistake.
Here is my React Js Code for API call,
fetch('localhost/learning-react/api/admin/signup', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
fname:fname,
lname:lname,
email:email,
uname:uname,
passwd:passwd
})
}).then((response) => response.json())
.then((responseJson) => {
if(responseJson['status']==='1')
{
alert(responseJson['msg']);
}
}
And This is My Yii2 Backend code,
public function actionSignup()
{
//$model = new TblUsers();
return "success";
}
Sorry For my Inability to finding mistakes in my code..!
First of all, 500 means generic server error. So you will need to post your error log as per my comment to help on that. However, I have found your code on the backend is wrong. You do not user restful controller in your code and as such it is not a REST API at all. So I advice you to read through Restful APIs in the Guide. That being said, you basically need to:
Create Restful controller by inheriting from yii\rest\Controller.
Return either Array, DataProvider or instance of yii\base\Model to have guarantee of automated serialization to JSON
so I will show you a simple example to give you an idea. Please read the guide to get in-depth insights on REST API with Yii2.
<?php
namespace app\modules\v1\controllers;
use yii\rest\Controller;
class LoginController extends Controller
{
public function actionSignup()
{
$model = new TblUsers();
//register a user
//return registred user
return [
'success' => true,
'member' => $model;
];
}
}
Let try the following, it may help.
You are making a rest post request, this means two things, first info will travel by POST request, and second dont forget its rest.
try opening the url in the browser, unless you define a rule it should open.
So go ahead open: http://localhost/learning-react/api/admin/signup you should see a "success" on the screen, or you will se the full 500 error printed.
If you were able to open the url on the browser, try the call again, and check your chrome debugger on the network tab. Look for the 500 error open it and read the error, it should be fully printed there on the response tab i.e.
when this is solved, don't forget to enable rules to allow only POST as request, and add the appropriate format for the response so you can consume it as json.
Yii::$app->response->format = Response::FORMAT_JSON;
Hope it helps debuggin.
This problem of displaying images on the angular client has disturbed me for long time, even after reading many similar questions. files are uploaded successful to the upload folder and the file details are stored in the mongodb database.
This is angular client. angular v1.6 after loading image data service or factory.
$scope.attachImages.push({
name: attachment.originalName,
filePath:attachment.upload_path
})
Then the html web page has this where I use the ng-src for image upload path.
<div layout = "column" ng-repeat ="image in attachImages">
<h5>{{image.name}}</h5>
<img ng-src="{{image.filePath}}"/>
</div>
But this is the error I get where it cannot load the images:
GET http://localhost:3010/client/upload/attachment/lion.jpg 404 (Not
Found)
this is what i did on the express nodejs backend server
router.get('/attachments/:cardId', function(req,res){
//load teh attachemnts from the db... imageId,
/// To get all the images/files stored in MongoDB
Attachment.find({card: req.params.cardId}, function(err,images){
if (err) {
res.json({"success": false, "message": 'Error finding the attachments'})
} else {
res.json({"success": true, "message": images})
//for teh single image..
router.get('/attachments/:cardId/:attachmentId',function(req,res){
Attachment.findOne({_id: req.params.attachmentId}, function(err, image){
if (err) {
res.json({"success": false, "message": 'ERror in finding the image'})
} else {
if (image) { //atleast there z content
//set the content-type correctly so our client or browser know how to handle it.
res.setHeader('Content-Type', image.mime);
//fs.createReadStream(path.join(UPLOAD_PATH, result.filename)).pipe(res);
//fs.createReadStream(path.join()).pipe(res);
res.send(image.upload_path);
}else {
res.json({"success": true, "message": 'No image data found'})
}
}
})
});
Please any help will be appreciated... Then later I'm going to talk about createObjectURL method, which does not show anything except gibberished arrays data.
I realised that i had made a mistake on the filePath while loading the images.
it is better for one to first test whether you can load images in the browser from their upload path first before sending the images.
just putting this express static handler before loading routes saved me after struggling for a week trying to load images.
app.use(express.static(__dirname + '/client'));
app.use(express.static(__dirname + '/client/upload/attachment'));
then load the express routes
//var user = require('./routes/user') //user routes
board = require('./routes/board'),
then on the angular client
if(attachName.match(/\.(jpg|jpeg|gif|png)$/)){ //u borrowed this from helper in nodejs
//console.log('yeah it z the image')
//$scope.attachImages.push(attachment);
$scope.attachImages.push({
name: attachment.originalName,
imageUrl: attachment.upload_path
})
Here is the thing:-
I have over a thousand images saved locally in my mac. I have a landing page that mocks an ecommerce deal site. It would be tedious to have to manually type in the src url in the img tag for a thousand pictures. Thus, i thought i could somehow have this images dumped in a cloud storage or something and use REST api get method to extract these images in a response.data. Then assign it to a $scope variable and use ng-repeat to bind the images in my landing page view. Is this possible? If not, what are the alternatives? SQL database?
Appreciate your help. P.S. I am totally a beginner at web development.
Install node.js. It's Javascript for a server which should make it pretty easy since you already know Javascript.
On a Mac, you can install node like this:
brew install node
Use this node.js code (credit to codepedia.com, tweaked a little by me):
//include http, fs and url module
var http = require('http'),
fs = require('fs'),
path = require('path'),
url = require('url');
imageDir = './images/';
//create http server listening on port 3333
http.createServer(function (req, res) {
//use the url to parse the requested url and get the image name
var query = url.parse(req.url,true).query;
pic = query.image;
if (typeof pic === 'undefined') {
getImages(imageDir, function (err, files) {
var imageList = JSON.stringify(files);
res.writeHead(200, {'Content-type':'application/json'});
res.end(imageList);
});
} else {
//read the image using fs and send the image content back in the response
fs.readFile(imageDir + pic, function (err, content) {
if (err) {
res.writeHead(400, {'Content-type':'text/html'})
console.log(err);
res.end("No such image");
} else {
//specify the content type in the response will be an image
res.writeHead(200,{'Content-type':'image/jpg'});
res.end(content, "binary");
}
});
}
}).listen(3333);
console.log("Server running at http://localhost:3333/");
//get the list of jpg files in the image dir
function getImages(imageDir, callback) {
var fileType = '.jpg',
files = [], i;
fs.readdir(imageDir, function (err, list) {
for(i=0; i<list.length; i++) {
if(path.extname(list[i]) === fileType) {
files.push(list[i]); //store the file name into the array files
}
}
callback(err, files);
});
}
Run this from the command line to start you new image server (assuming you named the file "server.js"):
node server.js
You should see this text appear on the command line:
Server running at http://localhost:3333/
You can quickly test it by going to this address in your browser and you should see a JSON object showing you an array of all the filenames in the "./images" directory. By the way, this program assumes you're putting the images folder in the same directory as "server.js". You can put the images directory anywhere and just change the path of the variable "imageDir".
Now you can load the list of files from Angular using this code in your controller:
$http.get("http://localhost:3333", function(data) {
$scope.images = data;
});
In your view, you can now use an ng-repeat like this to display all the images:
<div ng-repeat="image in images" style="padding: 8px">
<img src="http://localhost:3333/image={{ image }}">
</div>
Note: this will work if you run it locally on your Mac or if you upload all the images to a server on which you can use Node.js.
I'm quite new to REST and AngularJS, but after several hours of googling I couldn't find any answer to my question:
I'm trying to do a POST request from my angularjs frontend to my backend implemented in java (using JPA).
When I'm trying to create a json-object and to do a POST I always get the 415 (Unsupported Media Type) error.
(Actually I don't even get "into" the scope of the service (i.E. "IN SERVICE" doesn't get printed to the console)..
If I add postData.toJSON(), it actually gets "POSTed", but arrives null ...
how do I have to format my 'postData' in Order to succesfully get POSTed?
(I also tried to write the Date-properties without ' " ' - no luck...)
Thank you for your help!
FrontEnd:
app.controller('WorkController', function($scope, $http) {
$scope.saveWork = function () {
var postData = {
"status" : "OPEN",
"startDate": "1338364250000",
"endDate": "1336364253400",
"WorkText" : "Test"
};
$http.post("http://localhost:8080/service/v1/saveWork", postData)
.success(function(data, status, headers, config){
console.log("IN SAVE WORK - SUCCESS");
console.log(status);
})
.error(function(){
console.log("ERROR IN SAVE WORK!");
})
}
});
Service:
#POST
#Consumes(MediaType.APPLICATION_JSON)
public Response save(WorkDto wo){
System.out.println("IN SERVICE");
if(ass == null){
System.out.println("Could nor persist work- null");
return Response.noContent().build();
} else{
Work workDao = WorkTransformator.transform(wo);
workDao.persist();
return Response.ok().build();
}
}
Instead of building and sending a parsed JSON object, create a javascript object and send that in your post body. You can reuse your postData object, but try removing the "" surrounding properties names.
Try this:
var postData = {
status : "OPEN",
startDate: "1338364250000",
endDate: "1336364253400",
workText : "Test"
};
UPDATE
Looks like the above doesn't work by itself. I thought that the Content-Type would be infered.
Can you try to do the post request this way :
$http({
method: 'POST',
url: 'http://localhost:8080/service/v1/saveWork',
data: postData,
headers: {
'Content-Type': 'application/json'
}}); // complete with your success and error handlers...
// the purpose is to try to do the post request explicitly
// declaring the Content-Type you want to send.
UPDATE 2
If this didn't work, compose a post request using Fiddler, and check what's the response.
Here's some pointers:
Download Fiddler2 if you dont already have it
Compose a request like in the screenshot below
You can then check on the pane on the left for what was the server response code. Double click that line (Ignore the error code on the screenshot...you should be getting a 415)
After double-clicking the response line, you can check and browse for more details on the right pane:
If you can successfuly post with a «manufactured» JSON object then the problem resides on your Angular code. If not, it's certainly something wrong with your Rest Service configuration.
You can also inspect the details of your POSTS made with the Angular app in Fiddler2. That should give you a good insight of what's going on.
If you're into it, you can then update your question with some screenshots of your Angular app requests. That will certainly help us to help you :)
I finally managed to find the cause of my error!
In my Rest-Service, I directly expected my java-class as parameter. (I thought this would be parsed/deserialized automatically). Quite naive I think... :)
In order to get it working I had to:
-Expect a String as Parameter in my #POST service
-Deserialize it (using GSON)
Here is the (now working) service:
#POST
#Consumes(MediaType.APPLICATION_JSON)
public Response save(String wo){
if(wo == null){
System.out.println("Could nor persist work- null");
return Response.noContent().build();
} else{
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HHmm:ssZ").create();
WorkDto dto = gson.fromJson(wo, WorkDto.class);
Work workDao = WorkTransformator.transform(dto);
workDao.persist();
return Response.ok().build();
}
}
Thanks again António for your help!