New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Knockout web part with properties fails when running in SharePoint #233

Closed
davros85 opened this Issue Oct 12, 2016 · 9 comments

Comments

Projects
None yet
3 participants
@davros85

davros85 commented Oct 12, 2016

Thank you for reporting an issue or suggesting an enhancement. We appreciate your feedback - to help the team to understand your needs, please complete the below template to ensure we have the necessary details to assist you.

Category

  • Question
  • Typo
  • Bug
  • Enhancement / Suggestion
  • Additional article idea

Expected or Desired Behavior

That after building a new project based on the knockout template you should be able to run it in the Workbench within SharePoint.

Observed Behavior

When running in the local workbench, web part renders and custom properties are fine. When running in the Workbench in SharePoint, errors are logged below the web part. With a new, untouched project this is "Cannot read property 'description' of undefined".

Steps to Reproduce

Yo a new project using knockout, (fix the _description bug), and run it in the Workbench in a SharePoint dev tenant.

@manishgarg1

This comment has been minimized.

manishgarg1 commented Oct 12, 2016

Thanx for reporting. We will look into this.

@patmill

This comment has been minimized.

Contributor

patmill commented Oct 12, 2016

This is fixed in the next drop. For now, you can replace the _description variable in the generated code with _koDescription, and that will fix the issue.

@davros85

This comment has been minimized.

davros85 commented Oct 12, 2016

@patmill - this is not the same issue as already logged, it's when using any properties in the knockout template, then running it in the SharePoint workbench.

@manishgarg1

This comment has been minimized.

manishgarg1 commented Oct 12, 2016

Great.

From: Pat Miller [mailto:notifications@github.com]
Sent: Wednesday, October 12, 2016 9:34 AM
To: SharePoint/sp-dev-docs sp-dev-docs@noreply.github.com
Cc: Manish Garg (EXCHANGE) manishga@exchange.microsoft.com; Assign assign@noreply.github.com
Subject: Re: [SharePoint/sp-dev-docs] Knockout web part with properties fails when running in SharePoint (#233)

This is fixed in the next drop. For now, you can replace the _description variable in the generated code with _koDescription, and that will fix the issue.


You are receiving this because you were assigned.
Reply to this email directly, view it on GitHubhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FSharePoint%2Fsp-dev-docs%2Fissues%2F233%23issuecomment-253265935&data=01%7C01%7Cmanishga%40exchange.microsoft.com%7C1beb64e6f1b44022b97008d3f2bd822d%7C72f988bf86f141af91ab2d7cd011db47%7C1&sdata=3DjHD7h%2FSTWHV1KhoyUmMg4fKsAFl1bJUDAu06TReUY%3D&reserved=0, or mute the threadhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAB3Df22HVjl5R8HsyJ5Wi9XjZXKerESmks5qzQvbgaJpZM4KU6J7&data=01%7C01%7Cmanishga%40exchange.microsoft.com%7C1beb64e6f1b44022b97008d3f2bd822d%7C72f988bf86f141af91ab2d7cd011db47%7C1&sdata=scuamnDNNhcdqjldm18E0zUJhMXoDFYnMBy4cDbnUM0%3D&reserved=0.

@patmill

This comment has been minimized.

Contributor

patmill commented Oct 12, 2016

@davros85 - Got it, thanks. I read Knockout and Description, and jumped to the wrong answer.

@patmill

This comment has been minimized.

Contributor

patmill commented Oct 14, 2016

OK, picking up on this. The first issue is that the this.properties does not exist in the constructor, as we have not yet deserialized them. We added an extra step here to handle issues around persisted data schema drift (version 2 of the webpart expects data in a different format, so we need to give the developer a change to fix up the data that they were handed).

The right place to do most of this is in onInit. However, for some reason the compontentElement doesn't have the template HTML in it when it is being set. I'm not exactly a knockout expert, so having a bit of difficulty sorting out what the issue here is.

At any rate, to move to the next step, pull everything out of the constructor after
super(context);
this._id = _instance++;
and put it into onInit like so -

protected onInit<T>(): Promise<T>
{
  const tagName: string = `ComponentElement-${this._id}`;
  const componentElement: HTMLElement = this._createComponentElement(tagName);
  this._registerComponent(tagName);
  this.domElement.appendChild(componentElement);

  const bindings: IHelloWorldBindingContext = {
    description: this.properties.description,
    shouter: this._shouter
  };

  ko.applyBindings(bindings, this.domElement);

  this._koDescription.subscribe((newValue: string) => {
    this._shouter.notifySubscribers(newValue, 'description');
  });

  return Promise.resolve(null);
}
@patmill

This comment has been minimized.

Contributor

patmill commented Oct 14, 2016

OK, more information. Here's the workaround, as well as what the underlying bug is.

The underlying issue for why onInit() isn't working is that there is logic to handle onInit() taking too long that involves modifying the DOM to show a spinner. The spinner is supposed to be an overlay that is cleared, but currently is deletes the contents of the DOM, which wipes out the knockout stuff. So for now, do this:

0 - Update your constructor to look like this

public constructor(context: IWebPartContext) {
  super(context);
  this._id = _instance++;
}

1 - Create a new function

    private doInitStuff() : void
    {
      const tagName: string = `ComponentElement-${this._id}`;
      const componentElement: HTMLElement = this._createComponentElement(tagName);
      this._registerComponent(tagName);
      this.domElement.appendChild(componentElement);

      const bindings: IHelloWorldBindingContext = {
        description: this.properties.description,
        shouter: this._shouter
      };

      ko.applyBindings(bindings, this.domElement);

      this._koDescription.subscribe((newValue: string) => {
        this._shouter.notifySubscribers(newValue, 'description');
      });
    }

2 - Update your Render method to look like this

public render(): void {
  if ( !this.renderedOnce )
  {
    this.doInitStuff();
  }

  this._koDescription(this.properties.description);
}
@davros85

This comment has been minimized.

davros85 commented Oct 14, 2016

Brill - thanks - tried it and it works, fixes the undefined property issue as well as the web part disappearing.

@manishgarg1

This comment has been minimized.

manishgarg1 commented Jan 25, 2017

This is fixed now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment