Skip to content

Initialize cdk-tree component datasource in the constructor #15

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

Merged
merged 1 commit into from
Jun 1, 2023

Conversation

jzolnowski
Copy link

Due to an error Cannot read properties of undefined (reading 'getTreeData'), had to move datasource initialization to the constructor

@jzolnowski jzolnowski requested review from Splaktar and gkalpak May 21, 2023 14:33
Copy link

@gkalpak gkalpak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where/How did you get the error you mention on the commit message? I don't see how the changes in this PR could make any difference. Can you please give more details on the error and how the changes fix it?

@jzolnowski
Copy link
Author

jzolnowski commented May 29, 2023

@gkalpak @Splaktar - I managed to analyze the cause of the problem. The root cause of the issue is the tsconfig target ES2022. As it turns out targets ES2021 and ES2022 behave quite differently in some aspects. The following class:

class Data {    
    getTest() {
        return 'test';
    }
}

class Test {
    test1 = this.data.getTest();
    test2 = (() => { console.log("data", this.data)});

    constructor(private data: Data) {
        console.log("getData", this.data.getTest())
    }
}

const test = new Test(new Data())
test.test2();

will be compiled to the form (ES2021):

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class Data {
    getTest() {
        return 'test';
    }
}
class Test {
    constructor(data) {
        this.data = data;
        this.test1 = this.data.getTest();
        this.test2 = (() => { console.log("data", this.data); });
        console.log("getData", this.data.getTest());
    }
}
const test = new Test(new Data());
test.test2();

/*
Output:
[LOG]: "getData",  "test" 
[LOG]: "data",  Data: {} 
*/

On the other hand, setting the target to ES2022 we get:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class Data {
    getTest() {
        return 'test';
    }
}
class Test {
    data;
    test1 = this.data.getTest();
    test2 = (() => { console.log("data", this.data); });
    constructor(data) {
        this.data = data;
        console.log("getData", this.data.getTest());
    }
}
const test = new Test(new Data());
test.test2();

/*
Output:
[ERR]: Cannot read properties of undefined (reading 'getTest') 
*/

As we can see, after compiling, we refer to the class dependency at a time when we do not yet have a class reference created.
Hence, in target ES2022 we get the error

[ERR]: Cannot read properties of undefined (reading 'getTest') 

You can find similar differences in the static` class fields or decorators.

So the solution to our problem is to either initialize the fields of the class in the constructor or restore in tsconfig target to 2021

Copy link

@gkalpak gkalpak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great sleuthing, @jzolnowski 🕵️

This turns out to be a known issue with TypeScript (microsoft/TypeScript#52331) and it seems there are TS compiler bugs that prevent this from being properly reported as a compile-time error 😞 (microsoft/TypeScript#50971).

This NgPackagr issue also has some useful explanations, work-arounds and references with more details: ng-packagr/ng-packagr#2611

I took a brief look through the code-base and the CdkTreeComponent seems to be the only one that is affected by this.

The fix lgtm 👍

One more thing that needs addressing, though, is that we didn't get a test failure for this.
Is it because we don't cover this part of the app in e2e tests? Could you add a failing test case, @jzolnowski 🙏

@jzolnowski
Copy link
Author

One more thing that needs addressing, though, is that we didn't get a test failure for this.

@gkalpak we have this usecase covered
image

@jzolnowski jzolnowski force-pushed the fix/angular-cdk-tree-component branch from d9d9472 to e023fee Compare May 31, 2023 10:13
Copy link

@gkalpak gkalpak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I didn't realize that we don't run tests on CI for this repo 😅
Good to know that the e2e tests were actually failing 👍

@gkalpak gkalpak merged commit a5eaeee into master Jun 1, 2023
@gkalpak gkalpak deleted the fix/angular-cdk-tree-component branch June 1, 2023 11:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants