Issue with the PCF Navigation API

When we write react PCF controls, we are used to pass callbacks to the components. Some of this functions who might be passed, are the (context.navigation methods). Recently we had the feeling that it suddenly stopped working (ok, we used the context.navigation.navigateTo, which is not supported, so at first we thought it’s our fault). But it was something else.

The use-case

Let’s consider a react component, where we need to show an alert message.

const props : IAppComponentProps = {			
			openAlertDialog: context.navigation.openAlertDialog
ReactDOM.render(React.createElement(AppComponent, props), this.container)

And here the AppComponent

export interface IAppComponentProps {     
    openAlertDialog: (alertStrings: ComponentFramework.NavigationApi.AlertDialogStrings, options?: ComponentFramework.NavigationApi.AlertDialogOptions) => Promise<void>;

export const AppComponent = ({openAlertDialog} : IAppComponentProps ) : JSX.Element => {
    const clickMe=() => {       
    return <button onClick={clickMe}>Click me</button>;

When we click on the button, we expect an alert, right? But nothing happens.

The problem

The problem is that the navigation methods need a “this” context (ComponentFramework.NavigationApi might suggest that it’s namespace, but it’s not). Let’s have a look at how one of this methods are looking like:

So the method needs the “this” context, which we loose when we pass only the “openAlertDialog” callback.

The solution

[Edit] Solution 1: As Betim Beja pointed out, the best solution is to bind the methods to the context.navigation when passing them:

const props : IAppComponentProps = {			
			openAlertDialog: context.navigation.openAlertDialog.bind(context.navigation)
ReactDOM.render(React.createElement(AppComponent, props), this.container)

Solution 2: Another way is passing the whole navigation parameter:

const props : IAppComponentProps = {			
			navigation: context.navigation
ReactDOM.render(React.createElement(AppComponent, props), this.container)

And the component:

export interface IAppComponentProps {  
    navigation: any;  

export const AppComponent = ({navigation} : IAppComponentProps ) : JSX.Element => {

    const clickMe=() => {     
    return <button onClick={clickMe}>Click me</button>;

What about navigateTo

Unfortunately the “context.navigation.navigateTo” is not documented for PCFs, and is not listed in the TypeScript definitions. So basicaly unsupported. We know about it only from the Xrm sdk. I don’t know why it’s not documented, since is a very useful feature: allowing us for instance to open a form in a dialog without leaving the dataset control.
Right now it works (by using (context.navigation as any).navigateTo), but be careful using it: if one day it stops working, we are on our own.


6 thoughts on “Issue with the PCF Navigation API

Add yours

    1. One way or another we need to pass callback props. For nstance for the onChange callback, I also define an own method inside the index, because I need to call the notifyOutputChanges, which is not the job of the component. But if my method would do nothing else than calling a context method, why make the index more complicated than necessary? I just pass the method from the sdk as a callback prop. This blog wanted to point out that the navigation methods have issues with that (and I pretty much believe that this was not like this a few weeks ago).

      But regarding the context: lately I’ve started to think about it: what’s wrong with making use of react context to keep some pcf context stuff? Because in my opinion, the index shouldn’t be poluted with fetching data or metadata requests, or similar stuff. Sometimes I end up passing the webAPI from a component to the other, and that’s not right, so I’ll investigate on this . In case you have some documentation for/against this idea, I would appreaiate to have a link.

  1. Also I have a question, why we can’t just direct use Xrm? Since PCF always running on webpage, the Xrm object should be available all the time.

    1. First of all, it’s stated in the sdk that using the Xrm object for PCF is not supported: There must be a good reason the product team offered us possibilities to work without the Xrm object, and also write in the sdk that it’s not supported.
      Besides that, the PCFs are also for CanvasApps, where is no Xrm object.
      And last but not least, when you have a look to the announcement for PCFs, you can see that the whole Platform is in transition, so maybe the Xrm object won’t always be there in the future (here the link:

      1. Just found an interesting fact that remind us to carefully use Xrm in PCF. In the callback of navigateTo(that should triggered after dialog closed according MS doc), if Xrm is used in that place, it will became different object depend on the action in navigateTo target page.
        If add action was performed in target page, then after page closed, in that callback the Xrm will present the dialog context.
        If no action(or maybe others) was performed, when page closed, in that callback you will get PCF host page Xrm context.
        I guess that maybe one of reasons that some context methods are not available in PCF.

  2. Hello, thanks for the article!
    I tried to use openAlertDialog and openConfirmDialog from context.navigation in PCF control embedded to Canvas App (without D365), and I am getting:

    PCFControlWrapper.js: Uncaught PCFNonImplementedError: openAlertDialog: Method not implemented.

    Actually, according to the code, many methods of navigation interface just return “Method not implemented.” too.

    Do you know is it possible to somehow obtain PowerApps-style alert and confirm methods in canvas app?

    Thank you.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Website Powered by

Up ↑

%d bloggers like this: