salesforce / lwc

⚡️ LWC - A Blazing Fast, Enterprise-Grade Web Components Foundation
https://lwc.dev
Other
1.63k stars 394 forks source link

LWC1112: @api get connection and @api set connection detected in class declaration. Only one of the two needs to be decorated with @api. #2406

Closed AllanOricil closed 3 years ago

AllanOricil commented 3 years ago

Description

@api can't be placed in the set when the set is before the get image

This is valid image

It is only a error on the editor. ESLint does not catch this error. And this error is comming from lwc Another thing is that this error is not blocking the deployment of the component.

Steps to Reproduce

Just write a set followed by a get, and then add @api to the set. Then verify that this error message appears

Expected Results

the @api annotation should be valid in either get or set

Actual Results

the @api annotation displays an error messge when added to a set which is before the get

Browsers Affected

N/A

Version

N/A

Possible Solution

Additional context/Screenshots N/A

AllanOricil commented 3 years ago

I also opened it on the LWC Eslint recommnended preset. https://github.com/salesforce/eslint-config-lwc/issues/66 But later I noticed that it is not an ESLint error

AllanOricil commented 3 years ago

Apparently this is a regression

https://github.com/salesforce/lwc/issues/1113

AllanOricil commented 3 years ago

These are my devDependencies. Maybe I'm using an old package version?

"devDependencies": {
        "@prettier/plugin-xml": "^0.12.0",
        "@salesforce/eslint-config-lwc": "^0.7.0",
        "@salesforce/eslint-plugin-aura": "^1.4.0",
        "@salesforce/sfdx-lwc-jest": "^0.14.0",
        "eslint": "^7.6.0",
        "eslint-config-prettier": "^6.11.0",
        "husky": "^4.2.1",
        "lint-staged": "^10.0.7",
        "prettier": "2.3.2",
        "prettier-plugin-apex": "1.10.0"
    },
nolanlawson commented 3 years ago

Related: https://github.com/salesforce/eslint-config-lwc/issues/66

nolanlawson commented 3 years ago

Which LWC version are you using? What is the error message?

It seems to be working for me: https://webcomponents.dev/edit/h4dvbbJVyVZXKXxjBACz

import { LightningElement, api } from "lwc";

export default class extends LightningElement {
  _foo = 'foo'

  @api
  set foo (val) {
    this._foo = val
  }

  get foo () {
    return this._foo
  }

}
AllanOricil commented 3 years ago

@nolanlawson Im on a sfdx project

This is my sfdx-project.json

{
    "packageDirectories": [
        {
            "path": "salesforce_sfdx",
            "default": true
        }
    ],
    "namespace": "",
    "sfdcLoginUrl": "https://login.salesforce.com",
    "sourceApiVersion": "51.0"
}

this is my package.json

{
    "name": "salesforce-app",
    "private": true,
    "version": "1.0.0",
    "description": "Salesforce App",
    "scripts": {
        "lint": "npm run lint:lwc && npm run lint:aura",
        "lint:aura": "eslint salesforce_sfdx/**/aura/**",
        "lint:lwc": "eslint salesforce_sfdx/**/lwc/**",
        "test": "npm run test:unit",
        "test:unit": "sfdx-lwc-jest",
        "test:unit:watch": "sfdx-lwc-jest --watch",
        "test:unit:debug": "sfdx-lwc-jest --debug",
        "test:unit:coverage": "sfdx-lwc-jest --coverage",
        "prettier": "prettier --write \"**/*.{cls,cmp,component,css,html,js,md,page,trigger,xml,yaml,yml}\"",
        "prettier:verify": "prettier --list-different \"**/*.{cls,cmp,component,css,html,js,md,page,trigger,xml,yaml,yml}\""
    },
    "devDependencies": {
        "@prettier/plugin-xml": "^0.12.0",
        "@salesforce/eslint-config-lwc": "^0.7.0",
        "@salesforce/eslint-plugin-aura": "^1.4.0",
        "@salesforce/sfdx-lwc-jest": "^0.14.0",
        "eslint": "^7.6.0",
        "eslint-config-prettier": "^6.11.0",
        "husky": "^4.2.1",
        "lint-staged": "^10.0.7",
        "prettier": "2.3.2",
        "prettier-plugin-apex": "1.10.0"
    },
    "husky": {
        "hooks": {
            "pre-commit": "lint-staged"
        }
    },
    "lint-staged": {
        "**/*.{cls,cmp,component,css,html,js,md,page,trigger,xml,yaml,yml}": [
            "prettier --write"
        ],
        "**/{aura|lwc}/**": [
            "eslint"
        ]
    }
}

My VSCode version

Version: 1.58.0 (user setup)
Commit: 2d23c42a936db1c7b3b06f918cde29561cc47cd6
Date: 2021-07-08T06:54:55.083Z
Electron: 12.0.13
Chrome: 89.0.4389.128
Node.js: 14.16.0
V8: 8.9.255.25-electron.0
OS: Windows_NT x64 10.0.19043

My Node Version

v12.13.0
AllanOricil commented 3 years ago

This component that Im seeing this error has the following meta.xml file. It is using api 48.0 => Could it be a reason? I don't know, maybe the lwc compiler uses the api version declared in the xml?

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>48.0</apiVersion>
    <runtimeNamespace>vlocity_cmt</runtimeNamespace>
    <isExposed>true</isExposed>
    <description>Vlocity OmniScript Auto-generated - a303N0000006YMqQAM</description>
    <masterLabel>Agent/AllFlowsNewIssue/English</masterLabel>
    <targets>
        <target>lightningCommunity__Page</target>
        <target>lightningCommunity__Default</target>
        <target>lightning__RecordPage</target>
        <target>lightning__AppPage</target>
        <target>lightning__HomePage</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__AppPage, lightning__RecordPage">
            <property name="layout" type="String" datasource="lightning,newport"/>
            <property name="inline" type="boolean" default="false"/>
            <property name="inlineLabel" type="string" default="Launch Agent/AllFlowsNewIssue"/>
            <property name="inlineVariant" type="string" default="brand" datasource="brand,outline-brand,neutral,success,destructive,text-destructive,inverse,link"/>
            <property name="dir" type="string" default="ltr" datasource="ltr,rtl"/>
            <supportedFormFactors>
                <supportedFormFactor type="Large"/>
                <supportedFormFactor type="Small"/>
            </supportedFormFactors>
        </targetConfig>
        <targetConfig targets="lightning__HomePage">
            <property name="layout" type="String" datasource="lightning,newport"/>
            <property name="inline" type="boolean" default="false"/>
            <property name="inlineLabel" type="string" default="Launch Agent/AllFlowsNewIssue"/>
            <property name="inlineVariant" type="string" default="brand" datasource="brand,outline-brand,neutral,success,destructive,text-destructive,inverse,link"/>
            <property name="dir" type="string" default="ltr" datasource="ltr,rtl"/>
            <supportedFormFactors>
                <supportedFormFactor type="Large"/>
            </supportedFormFactors>
        </targetConfig>
        <targetConfig targets="lightningCommunity__Default">
            <property name="layout" type="String" datasource="lightning,newport"/>
            <property name="inline" type="boolean" default="false"/>
            <property name="inlineLabel" type="string" default="Launch Agent/AllFlowsNewIssue"/>
            <property name="inlineVariant" type="string" default="brand" datasource="brand,outline-brand,neutral,success,destructive,text-destructive,inverse,link"/>
            <property name="recordId" type="String" label="Record Id" description="Automatically bind the page's record id to the component variable" default="{!recordId}"/>
            <property name="dir" type="string" default="ltr" datasource="ltr,rtl"/>
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>
pmdartus commented 3 years ago

If this issue is reported in VSCode only, it means that it is a language server issue. I am not able to reproduce this issue locally after creating a brand new SFDX project and updating all the Salesforce VSCode extensions. I don't think it is a regression, there are tests in place for setter/getter and getter/setter:

https://github.com/salesforce/lwc/blob/d93e2963d8d32b138ce9ed130d98e7bef84b3d74/packages/%40lwc/babel-plugin-component/src/__tests__/api-decorator.spec.js#L219-L232

This issue should be reported against forcedotcom/lightning-language-server.

ytiq commented 2 years ago

found an example that fails it @pmdartus.

import { LightningElement, api } from 'lwc';

export default class Testsdfsdf extends LightningElement {
    @api get b() {}
    @api set a(value) { }
    get a() {}
}

If anywhere in your code you have @api getter, then it fails other parts where you have @api setter

AllanOricil commented 2 years ago

@ytiq open an issue in this repo https://github.com/forcedotcom/lightning-language-server

ytiq commented 2 years ago

ok, will do

ytiq commented 2 years ago

@AllanOricil seems like https://github.com/forcedotcom/lightning-language-server is not being maintained since there are no comments on issues since August

AllanOricil commented 2 years ago

@pmdartus @nolanlawson I confirm @ytiq isolated the problem correctly. It is not an issue related to vscode not loading the language server.

steps:

1 - create a lwc with the following code

import { LightningElement, api } from 'lwc';

export default class Test extends LightningElement {

    @api set test1(value){}
    get test2(){}
}

2 - verify it does work and no language server error is present 3 - change the lwc code to this one

import { LightningElement, api } from 'lwc';

export default class Test extends LightningElement {

    @api set test1(value){}
    @api get test2(){}
}

4 - verify that now you have the error from this issue 5 - conclude that in a class you can't decorate a getter and a setter with @api. You must choose one of them in the whole js file to decorate with @api. In other words, either all getters are decorated with @api, or all setters.

geoffswift commented 9 months ago

First of all, if we want to decorate both the getter and setter, then why not allow it? This seems an unnecessary restriction.

It would also make more sense to actually require the opposite, i.e. both the getter / setter must be decorated. Have a read of the proposal for decorators here https://github.com/tc39/proposal-decorators?tab=readme-ov-file#class-accessors...

Accessor decorators are applied separately to getters and setters. In the following example, @foo is applied only to get x() - set x() is undecorated:

class C {
  @foo
  get x() {
    // ...
  }

  set x(val) {
    // ...
  }
}