Reputation: 127
I'm working on a React project.
I'm able to sign in in the graph API, also able to get the user's contacts, but, not able to get his calendar events.
the config file:
export const msalConfig = {
auth: {
clientId: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
authority: "https://login.microsoftonline.com/common",
redirectUri: "http://localhost:4200",
},
cache: {
cacheLocation: "sessionStorage", // This configures where your cache will be stored
storeAuthStateInCookie: true, // Set this to "true" if you are having issues on IE11 or Edge
}
};
// Add scopes here for ID token to be used at Microsoft identity platform endpoints.
export const loginRequest = {
scopes: ["Calendars.ReadWrite", "Contacts.Read"]
};
// Add the endpoints here for Microsoft Graph API services you'd like to use.
export const graphConfig = {
graphMeEndpoint: "https://graph.microsoft.com/v1.0/me",
graphCalendarsEndpoint: "https://graph.microsoft.com/v1.0/me/events",
graphContactsEndpoint: "https://graph.microsoft.com/v1.0/me/contacts",
};
1/ The working part
the importContact.jsx file:
...
import { loginRequest, graphConfig } from '../authConfig.jsx';
import { useMsal } from "@azure/msal-react";
const ImportContacts = (props) => {
const { instance, accounts, inProgress } = useMsal();
const [accessToken, setAccessToken] = useState(null);
const [graphData, setGraphData] = useState(null);
const getMicrosoftContacts = () => {
const request = {
...loginRequest,
account: accounts[0]
};
var contacts= [];
// Silently acquires an access token which is then attached to a request for Microsoft Graph data
instance.acquireTokenSilent(request).then((response) => {
console.log('acquireTokenSilent')
setAccessToken(response.accessToken);
callMsGraph(response.accessToken).then(
response => {
setGraphData(response);
console.log(response)
for (const item of response.value){
contacts.push({
provider: 'Microsoft',
id: item.id,
email: item.emailAddresses[0].address,
firstName: item.givenName,
lastName: item.surname,
name: item.displayName,
label:item.displayName + " (" + item.emailAddresses[0].address + ")" }
)
}
setItems(contacts);
}
);
}).catch((e) => {
instance.acquireTokenPopup(request).then((response) => {
setAccessToken(response.accessToken);
callMsGraph(response.accessToken).then(
response => {
setGraphData(response);
for (const item of response.value){
contacts.push({
provider: 'Microsoft',
id: item.id,
email: item.emailAddresses[0].address,
firstName: item.givenName,
lastName: item.surname,
name: item.displayName,
label:item.displayName }
)
}
setItems(contacts);
}
);
});
});
}
async function callMsGraph(accessToken) {
const headers = new Headers();
const bearer = `Bearer ${accessToken}`;
headers.append("Authorization", bearer);
const options = {
method: "GET",
headers: headers
};
return fetch(graphConfig.graphContactsEndpoint, options)
.then(response => response.json())
.catch(error => console.log(error));
}
...
}
2/ The non working part in events.jsx file:
...
import { loginRequest, graphConfig } from '../authConfig.jsx';
import { useMsal } from "@azure/msal-react";
class Events extends Component {
constructor(props) {
super(props);
this.getMicrosoftEvents = this.getMicrosoftEvents.bind(this);
}
componentDidMount(){
var date = new Date();
var firstDay = new Date(date.getFullYear(), date.getMonth(), 1);
var lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0);
this.getMicrosoftEvents(firstDay, lastDay);
}
getMicrosoftEvents(start, end) {
console.log('log displayed in console')
const { instance, accounts, inProgress } = useMsal();
const [accessToken, setAccessToken] = useState(null);
const [graphData, setGraphData] = useState(null);
console.log('log not displayed in console')
const request = {
...loginRequest,
account: accounts[0]
};
// Silently acquires an access token which is then attached to a request for Microsoft Graph data
instance.acquireTokenSilent(request).then((response) => {
console.log('acquireTokenSilent')
setAccessToken(response.accessToken);
callMsGraph(response.accessToken, start, end).then(
response => {
console.log('microsoft response ' + response)
}
);
}).catch((e) => {
console.log('microsoft response error ' + e)
instance.acquireTokenPopup(request).then((response) => {
setAccessToken(response.accessToken);
callMsGraph(response.accessToken, start, end).then(
response => {
console.log('microsoft response ' + response)
}
);
});
});
async function callMsGraph(accessToken, start, end) {
console.log('callMsGraph ')
const headers = new Headers();
const bearer = `Bearer ${accessToken}`;
headers.append("Authorization", bearer);
console.log('Authorization ' + bearer)
const options = {
method: "GET",
headers: headers
};
return fetch(graphConfig.graphCalendarsEndpoint
+ '?startDateTime='
+ start
+ '&endDateTime='
+ end,
options)
.then(response => {
console.log('microsoft response ' + response.json())
response.json();
})
.catch(error => console.log(error));
}
}
I'm not getting any error, the api call is not made, the difference between the two calls is one is made after a button click, and the other on load.
Adding logs showed me that the problem could be in this line as the logs are not displayed after it:
const { instance, accounts, inProgress } = useMsal();
What am I doing wrong?
Upvotes: 0
Views: 1375
Reputation: 1771
In events.jsx
Events component is a class component and you are calling useMsal()
and useState()
hooks in getMicrosoftEvents
. That will not work because hooks can only be called in function components.
You need to make Events component functional like ImportContacts
.
Instead of
class Events extends Component {
...
Do this
const Events= (props) => {
const { instance, accounts, inProgress } = useMsal();
const [accessToken, setAccessToken] = useState(null);
const [graphData, setGraphData] = useState(null);
...
Upvotes: 1