Deepak Kothari
Deepak Kothari

Reputation: 1763

Is there an easy way to display the profile image from graph api in a react application

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?

enter image description here

Upvotes: 4

Views: 8968

Answers (4)

Mike
Mike

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

kurtis_dev
kurtis_dev

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

Deepak Kothari
Deepak Kothari

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

Danstan
Danstan

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

Related Questions