I need help, I am trying out to create an SPFx Application customizer. Its pretty simple, I just wanted to call a components from the main components.
Here is my code
src\extensions\emergencyBanner\EmergencyBannerApplicationCustomizer.ts
import { Log } from '@microsoft/sp-core-library';
// import * as React from 'react';
// import * as ReactDom from "react-dom";
import {
BaseApplicationCustomizer,
PlaceholderContent,
PlaceholderName,
} from "@microsoft/sp-application-base";
import { Dialog } from '@microsoft/sp-dialog';
import * as strings from 'EmergencyBannerApplicationCustomizerStrings';
import * as React from 'react';
import { IMainComponentProps } from "./components/IMainComponentProps";
import MainComponent from "./components/MainComponent";
// import { spfi, SPFx } from "@pnp/sp";
// import { IMainComponentProps } from "./components/IMainComponentProps";
// import MainComponent from "./components/MainComponent";
const LOG_SOURCE: string = 'EmergencyBannerApplicationCustomizer';
/**
* If your command set uses the ClientSideComponentProperties JSON input,
* it will be deserialized into the BaseExtension.properties object.
* You can define an interface to describe it.
*/
export interface IEmergencyBannerApplicationCustomizerProperties {
// This is an example; replace with your own property
testMessage: string;
}
/** A Custom Action which can be run during execution of a Client Side Application */
export default class EmergencyBannerApplicationCustomizer
extends BaseApplicationCustomizer<IEmergencyBannerApplicationCustomizerProperties> {
private static _topPlaceholder: PlaceholderContent | undefined;
public onDispose() {
if (
EmergencyBannerApplicationCustomizer._topPlaceholder &&
EmergencyBannerApplicationCustomizer._topPlaceholder.domElement
) {
// ReactDom.unmountComponentAtNode(
// EmergencyBannerApplicationCustomizer._topPlaceholder.domElement
// );
}
}
private render() {
if (
this.context.placeholderProvider.placeholderNames.indexOf(
PlaceholderName.Top
) !== -1
) {
if (
!EmergencyBannerApplicationCustomizer._topPlaceholder ||
!EmergencyBannerApplicationCustomizer._topPlaceholder.domElement
) {
EmergencyBannerApplicationCustomizer._topPlaceholder =
this.context.placeholderProvider.tryCreateContent(
PlaceholderName.Top,
{
onDispose: this.onDispose,
}
);
}
this.startReactRender();
} else {
console.log(
`The following placeholder names are available`,
this.context.placeholderProvider.placeholderNames
);
}
}
/**
* Start the React rendering of your components
*/
private startReactRender(): void {
if (
!EmergencyBannerApplicationCustomizer._topPlaceholder ||
!EmergencyBannerApplicationCustomizer._topPlaceholder.domElement
) {
EmergencyBannerApplicationCustomizer._topPlaceholder =
this.context.placeholderProvider.tryCreateContent(
PlaceholderName.Top,
{
onDispose: this.onDispose,
}
);
}
if (
EmergencyBannerApplicationCustomizer._topPlaceholder &&
EmergencyBannerApplicationCustomizer._topPlaceholder.domElement
) {
const element: React.ReactElement<IMainComponentProps> =
React.createElement(MainComponent, {
description: "Test"
});
if (this.properties) {
let topString: string = this.properties.testMessage;
if (!topString) {
topString = "(Top property was not defined.)";
}
if (EmergencyBannerApplicationCustomizer._topPlaceholder.domElement) {
EmergencyBannerApplicationCustomizer._topPlaceholder.domElement.innerHTML = `
<div>
<div>
<i class="ms-Icon ms-Icon--Info" aria-hidden="true"></i> ${escape(
topString
)}
</div>
</div>`;
}
}
} else {
console.log(
"DOM element of the header is undefined. Start to re-render."
);
this.render();
}
}
public onInit(): Promise<void> {
Log.info(LOG_SOURCE, `Initialized ${strings.Title}`);
let message: string = this.properties.testMessage;
if (!message) {
message = '(No properties were provided.)';
}
this.context.application.navigatedEvent.add(this, () => {
this.startReactRender();
});
Dialog.alert(`Hello from ${strings.Title}:\n\n${message}`).catch(() => {
/* handle error */
});
return Promise.resolve();
}
}
and here is my src\extensions\emergencyBanner\components\MainComponent.tsx
import * as React from "react";
import { IMainComponentProps } from "./IMainComponentProps";
const MainComponent: React.FunctionComponent<IMainComponentProps> = ({
description
}) => {
return (<div>{description}</div>)
};
export default MainComponent;
Here is my interface from my MainComponent
import { ApplicationCustomizerContext } from "@microsoft/sp-application-base";
import { SPFI } from "@pnp/sp";
export interface IMainComponentProps {
// context: ApplicationCustomizerContext;
// spfi: SPFI;
description: string;
}
But somehow in my gulp serve, in my browser I am getting this error in console
sp-pages-assembly_en-us_3edfa0c17b40c4b8bbbaae5e3a144e6a.js:207 Could not load emergency-banner-application-customizer in require. TypeError: Cannot read properties of undefined (reading 'id')
Downgrade to this version. Clean the package-lock and node modules. Should work fine
npm i react@17.0.1 react-dom@17.0.1 --save