Reputation: 1763
I am looking for an easy way to display the image response from graph api into the react application. Something like this https://blogs.aaddevsup.xyz/2020/05/how-to-get-and-display-the-user-photo-with-graph-sdk-for-net-in-a-wpf-application/
When I try I get this from the api, not sure what format the response is in and how to convert and show it as image?
Upvotes: 4
Views: 8968
Reputation: 596
A slightly tweaked version of @Danstan's answer, for anyone wishing to use fetch instead of Axios:
export async function getUserPhotoUrl(accessToken) {
const headers = new Headers();
const bearer = `Bearer ${accessToken}`;
headers.append("Authorization", bearer);
const options = {
method: "GET",
headers: headers,
responseType: "blob",
};
return fetch("https://graph.microsoft.com/v1.0/me/photo/$value", options)
.then((response) => response.blob())
.then((blob) => {
const url = window.URL || window.webkitURL;
const blobUrl = url.createObjectURL(blob);
return blobUrl;
});
}
Upvotes: 0
Reputation: 101
I've got mine working without importing a new library for the api request. Hope the below helps anyone that's stuck.
My downfall was not specifying the dimensions for the image. If you don't do this it won't render.
useEffect(() => {
GetProfilePicture()
}, [])
const [image, setImage] = useState()
const [isOk, setResponse] = useState()
const GetProfilePicture = async () => {
const headers = new Headers();
const bearer = 'Bearer ${props.token}';
headers.append("Authorization", bearer);
headers.append("Content-type", 'image/jpeg');
const options = {
method: "GET",
headers: headers,
};
await fetch("https://graph.microsoft.com/v1.0/me/photo/$value", options)
.then(response => {
response.blob().then((data) => {
const reader = new FileReader()
reader.readAsDataURL(data)
reader.onload = () => {
const base64data = reader.result;
setImage(base64data)
setResponse(response.ok)
}
})
})
}
const ProfilePic = () => {
if (isOk != false) {
return (
<Image style={{height: 90, width: 90}} key={image} source={{uri: image}}></Image>
)
} else {
return (
<Fragment></Fragment>
)
}
}
Upvotes: 1
Reputation: 1763
I tried different approaches and finally this worked for me.
useEffect(() => {
const getPhoto = async () => {
const graphEndpoint = "https://graph.microsoft.com/v1.0/me/photo/$value";
const response = await axios(graphEndpoint, {
headers: { Authorization: `Bearer ${sessionStorage.getItem("accesstoken")}` },
responseType: "arraybuffer"
});
const avatar = Buffer.from(response.data, "binary").toString("base64");
setPhotoData("data:image/jpeg;base64, " + avatar);
};
getPhoto();
}, []);
Upvotes: 4
Reputation: 1791
MS Graph Docs - Using the binary data of the requested photo has some helpful note.
Here is a sample component pulled from the docs. Note am using Axios to fetch the photo using responseType: 'blob' config and render it when I have it.
I could not get it to work without that config.
import { useEffect, useState } from 'react';
import Axios from 'axios'
function App() {
const [imageUrl, setImageUrl] = useState(null)
useEffect(() => {
Axios.get('https://graph.microsoft.com/v1.0/me/photo/$value', {
headers: { 'Authorization': 'Bearer eyJ...' },
responseType: 'blob'
}).then(o => {
const url = window.URL || window.webkitURL;
const blobUrl = url.createObjectURL(o.data);
setImageUrl(blobUrl)
})
}, [])
return (
<div className="App">
{imageUrl && <img alt='my-user-avatar' src={imageUrl} />}
</div>
);
}
export default App;
FYI, you may also be interested in using MS Graph UI Toolkit for Reactjs as you seem to be rendering user profile card.
Upvotes: 6