Problems with MSGraph POST in SPFx React
-
08-02-2021 - |
Question
I am fairly new to MSGraph and I have a problem with the POST request. I am currently building an app in SharePoint Framework with React which should send a message to the typed email with subject and message.
Here I send my file structure:
Here is the SendmailWebPart.ts file:
import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library';
import {
BaseClientSideWebPart,
IPropertyPaneConfiguration,
PropertyPaneTextField
} from '@microsoft/sp-webpart-base';
import * as strings from 'SendmailWebPartStrings';
import Sendmail from './components/Sendmail';
import { ISendmailProps } from './components/ISendmailProps';
import { MSGraphClientFactory, MSGraphClient } from '@microsoft/sp-http';
export interface ISendmailWebPartProps {
description: string;
}
export default class SendmailWebPart extends BaseClientSideWebPart<ISendmailWebPartProps> {
public render(): void {
const element: React.ReactElement<ISendmailProps > = React.createElement(
Sendmail,
{
description: this.properties.description,
spfxContext: this.context
}
);
this.context.msGraphClientFactory
.getClient()
.then((client: MSGraphClient): void => {
client
.api('/me')
.get((error, response: any, rawResponse?: any) => {
console.log("Any Graph Response? " + JSON.stringify(response));
})
});
ReactDom.render(element, this.domElement);
}
protected onDispose(): void {
ReactDom.unmountComponentAtNode(this.domElement);
}
protected get dataVersion(): Version {
return Version.parse('1.0');
}
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return {
pages: [
{
header: {
description: strings.PropertyPaneDescription
},
groups: [
{
groupName: strings.BasicGroupName,
groupFields: [
PropertyPaneTextField('description', {
label: strings.DescriptionFieldLabel
})
]
}
]
}
]
};
}
}
Sendmail.tsx:
import * as React from 'react';
import styles from './Sendmail.module.scss';
import { ISendmailProps } from './ISendmailProps';
import { escape } from '@microsoft/sp-lodash-subset';
import { EmailForm } from './EmailForm'
export default class Sendmail extends React.Component<ISendmailProps, {}> {
public render(): React.ReactElement<ISendmailProps> {
return (
<div className={ styles.sendmail }>
<div className={ styles.container }>
<div className={ styles.row }>
<div className={ styles.column }>
<span className={ styles.title }>Welcome to SharePoint messenger!</span>
<EmailForm description={this.props.description} spfxContext={this.context}></EmailForm>
</div>
</div>
</div>
</div>
);
}
}
ISendmailProps.ts:
import { WebPartContext } from "@microsoft/sp-webpart-base";
export interface ISendmailProps {
description: string;
spfxContext: WebPartContext;
}
export interface ISendmailState {
emailTo: string;
subject: string;
message: string;
}
And finally here is the component EmailForm.tsx in which I have the issue:
import * as React from 'react';
import styles from './Sendmail.module.scss';
import { ISendmailProps, ISendmailState } from './ISendmailProps';
import { escape } from '@microsoft/sp-lodash-subset';
import { TextField, PrimaryButton } from 'office-ui-fabric-react';
import { MSGraphClientFactory, MSGraphClient } from '@microsoft/sp-http';
import { ServiceKey } from '@microsoft/sp-core-library';
export class EmailForm extends React.Component<ISendmailProps, ISendmailState>{
/**
*
*/
constructor(props) {
super(props);
this.state = {
emailTo: 'dddddddddd.cx',
subject: 'dsdsd',
message: 'dsdsdsdsdcdcdcdcdcdcdc'
}
}
//Render Email. Show the attributes
public render(): React.ReactElement<ISendmailState> {
return(
<div>
<TextField label="Email to " value={this.state.emailTo} onChange={this._handleMailTo.bind(this)} required />
<TextField label="Subject " value={this.state.subject} onChange={this._handleSubject.bind(this)} required />
<TextField label="Message " value={this.state.message} onChange={this._handleMessage.bind(this)} multiline rows={3} />
<PrimaryButton text="Send Message" onClick={() => {this._sendEmail(event)} } />
</div>
)
}
//Method
private _handleMailTo(e) {
this.setState({
emailTo: e.target.value,
});
}
private _handleSubject(e) {
this.setState({
subject: e.target.value
});
}
private _handleMessage(e) {
this.setState({
message: e.target.value
});
}
//Send Email
private async _sendEmail(e): Promise<void> {
alert("Email Sent!");
console.log(this.state.emailTo);
console.log(this.state.subject);
console.log(this.state.message);
const graphClient : MSGraphClient = this.context.serviceScope.consume(MSGraphClient.serviceKey)
const options = {
authProvider,
};
const myClient = Client.init(options);
const sendMail = {
message: {
subject: this.state.subject,
body: {
contentType: "Text",
content: this.state.message
},
toRecipients: [
{
emailAddress: {
address: this.state.emailTo
}
}
],
}
};
let res = await myClient.api('/me/sendMail')
.post(sendMail);
}
}
The problem is, I don't understand why when I type :
this.context.serviceScope.consume(MSGraphClient.serviceKey)
servicekey doesn't exist because I have seen someone else doing it without errors.
And the second problem is with authProvider and Client even though I am following this documentation: https://docs.microsoft.com/en-us/graph/api/user-sendmail?view=graph-rest-1.0&tabs=javascript
Here I will provide a screenshot of the errors:
Here are my approved Graph API:s in API-management:
I would appreciate if someone please could help me out here. Thank you very much in advance.
La solution
Sample demo to send email. this.props.context
the context is from webpart(.ts).
const sendMail = {
message: {
subject: "Test",
body: {
contentType: "Text",
content: "test email in SPFx call."
},
toRecipients: [
{
emailAddress: {
address: "lee@xxx.onmicrosoft.com"
}
}
],
ccRecipients: [
{
emailAddress: {
address: "lee@xxx.onmicrosoft.com"
}
}
]
},
saveToSentItems: "false"
};
this.props.context.msGraphClientFactory
.getClient()
.then((client: MSGraphClient): void => {
// get information about the current user from the Microsoft Graph
client
// .api('/me')
// .get((error, response: any, rawResponse?: any) => {
// let user = response.displayName;
// });
.api('/me/sendMail')
.post(sendMail).then(()=>{
console.log('email send');
})
});
Autres conseils
This doesn't answer all your question, but this is to the first error MSGraphClient.serviceKey
,
Since 1.6 the MSGraphClient and AadHttpClient classes no longer expose a serviceKey property which means that we cannot get hold of the default instances in custom services without passing in the entire web part context.
We get this error:
Property 'serviceKey' does not exist on type 'typeof MSGraphClient'