Zt-freak / DevOpsWorkItemRESTRequestButton

Adds a custom control with a button that sends a REST request.
https://marketplace.visualstudio.com/items?itemName=Apodemus.RESTRequestButton
MIT License
3 stars 3 forks source link

Error when I click the button (the JS method toLowerCase() is undefined for booleans) #107

Closed AoooR42 closed 1 year ago

AoooR42 commented 1 year ago

Hello, I have just installed your extension and add a button to a work item (with TFS2018). The problem is, when I click the button, I have an error in the browser console:

Uncaught (in promise) TypeError: o.getConfiguration(...).witInputs.SendUser.toLowerCase is not a function
    at n.<anonymous> (RESTRequestButton.js:2:412581)
    at RESTRequestButton.js:2:410407
    at Object.next (RESTRequestButton.js:2:410512)
    at RESTRequestButton.js:2:409403
    at new Promise (<anonymous>)
    at c (RESTRequestButton.js:2:409148)
    at RESTRequestButton.js:2:412143

I wanted to see where the error was coming from, and noticed that o.getConfiguration().witInputs.SendUser is a boolean, so "false" == o.getConfiguration().witInputs.SendUser.toLowerCase() doesn't work (toLowerCase() doesn't exist on a boolean, I think you'd have to use it directly as a boolean rather than converting it to a string). I guess there's no real error, and it's just me, maybe I missed something in the installation? I have the impression that it's linked to the conversion of the typescript code into javascript. (This error corresponds to line 96 of the RESTRequestButton.tsx file)

Thanks in advance for your help :)

Zt-freak commented 1 year ago

I will look into it. Debugging has revealed that SendUser is a string and not a boolean.

Zt-freak commented 1 year ago

what does your setting look like in your configuration?

AoooR42 commented 1 year ago

Where? Initialy I just added the extension from the store, to my TFS2018 organization. Then I modified the XML configuration file of the work item to which I added a button, it looks like this:

[...]
      <WebLayout ShowEmptyReadOnlyFields="true">
        <!--**********************Extensions d'élément de travail**********************

Extension :
    Nom: RESTRequestButton
    ID: Apodemus.RESTRequestButton

    Contribution de contrôle:
        ID: Apodemus.RESTRequestButton.RESTRequestButton
        Description: 
        Entrées:
            ID: ButtonTitle
            Description: Text you want displayed on the button
            Type de données: String
            IsRequired: true

            ID: Fields
            Description: Work item fields you wish to collect for sending, comma-separated
            Type de données: String
            IsRequired: true

            ID: Endpoint
            Description: URL you want to send your data to
            Type de données: String
            IsRequired: true

            ID: CustomSender
            Description: Custom sender id (default: "WorkItemRESTRequestButton")
            Type de données: String
            IsRequired: false

            ID: SendUser
            Description: true, false
            Type de données: Boolean
            IsRequired: true

            ID: ShowResponseBody
            Description: true, false
            Type de données: Boolean
            IsRequired: true

            ID: ShowErrorAlertBox
            Description: true, false
            Type de données: Boolean
            IsRequired: false

            ID: Method
            Description: *GET, POST, PUT, DELETE, etc.
            Type de données: String
            IsRequired: false

            ID: Mode
            Description: no-cors, *cors, same-origin
            Type de données: String
            IsRequired: false

            ID: Cache
            Description: *default, no-cache, reload, force-cache, only-if-cached
            Type de données: String
            IsRequired: false

            ID: Credentials
            Description: include, *same-origin, omit
            Type de données: String
            IsRequired: false

            ID: Redirect
            Description: manual, *follow, error
            Type de données: String
            IsRequired: false

            ID: ReferrerPolicy
            Description: no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
            Type de données: String
            IsRequired: false

            ID: Authorization
            Description: Auth string
            Type de données: String
            IsRequired: false

            ID: ShouldUseDefaultBearer
            Description: true, false (default: true)
            Type de données: Boolean
            IsRequired: false

[...]
Remarque : Pour plus d'informations sur les extensions d'élément de travail, consultez la rubrique suivante :
http://go.microsoft.com/fwlink/?LinkId=816513
-->
        <Extensions>
          <Extension Id="Apodemus.RESTRequestButton" />
[...]
        </Extensions>
[...]
        <Page Label="*****" LayoutMode="EqualColumns">
          <Section>
            <Group Label="*****">
[...]
              <ControlContribution Label="*****" Id="Apodemus.RESTRequestButton.RESTRequestButton">
                <Inputs>
                  <Input Id="ButtonTitle" Value="*****" />
                  <Input Id="Fields" Value="System.Title, System.AssignedTo" />
                  <Input Id="Endpoint" Value="https://*****:1622/*****" />
                  <Input Id="SendUser" Value="true" />
                  <Input Id="ShowResponseBody" Value="true" />
                  <Input Id="Method" Value="POST" />
                </Inputs>
              </ControlContribution>
            </Group>
          </Section>
[...]
        </Page>
      </WebLayout>
    </FORM>
  </WORKITEMTYPE>
</witd:WITD>

I did nothing more, and the Javascript variables for SendUser and ShowResponseBody are booleans. The patch I did in the PR #108 works for me, so I'm going to keep it anyway. But it's true that it's odd that you have Strings when in the XML file you define booleans. Perhaps strong typing in Typescript rather than using any could solve the problem? Or at least help find its origin. Let me know if I can give you more information to help solve the problem.

AoooR42 commented 1 year ago

I've just thought of a workarround until we find the real solution. In Javascript, true.ToString() returns the String 'true', and "true".toString() also return the String 'true'. So maybe we can use it to force to convert booleans/String to String, then use .toLowerCase() == "true".

So for example on RESTRequestButton.tsx line 96: your SDK.getConfiguration().witInputs["SendUser"].toLowerCase() != "false" and my SDK.getConfiguration().witInputs["SendUser"] === true can be merged: SDK.getConfiguration().witInputs["SendUser"].toString().toLowerCase() != "false"

Zt-freak commented 1 year ago

Yeah I have only tested it on Azure DevOps and when I inspect it there it is a string. I think your last solution could work.

AoooR42 commented 1 year ago

Ok, I will update my PR

Zt-freak commented 1 year ago

thanks for the contribution! man, don't you love it when Microsoft is "consistent" across its platforms.