Skip to content
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

findRecord returns null on second call #8125

Closed
law-rence opened this issue Aug 15, 2022 · 6 comments · Fixed by #8128
Closed

findRecord returns null on second call #8125

law-rence opened this issue Aug 15, 2022 · 6 comments · Fixed by #8128

Comments

@law-rence
Copy link
Contributor

law-rence commented Aug 15, 2022

Reproduction

// userId is the same in both calls
// first call
this.store.findRecord("user", userId).then( result => { return result; } ) // result -> expected data for User

// time between the calls, lets assume a few seconds. nothing else was done between the two calls.

// second call, call findRecord on user again
this.store.findRecord("user", userId).then( result => { return result; } ) // result -> null

If I use peekRecord for the second call, the result is the expected model object, since it is already loaded into the store.
If I use the option reload:true for the second call, it works as well and the result is the expected model object.

Description

FindRecord returns null after trying to get the record for the same ID the second time. In my test case it was a user. The issue occurs at commit 7e66606. In the commit d84c443 it is still working as expected.

Versions

yarn list v1.22.19
warning Filtering by arguments is deprecated. Please use the pattern option instead.
└─ ember-source@4.6.0
Done in 0.62s.
yarn list v1.22.19
warning Filtering by arguments is deprecated. Please use the pattern option instead.
└─ ember-cli@4.6.0
Done in 0.67s.
yarn list v1.22.19
├─ @ember-data/adapter@4.8.0-alpha.3
├─ @ember-data/canary-features@4.8.0-alpha.3
├─ @ember-data/debug@4.8.0-alpha.3
├─ @ember-data/model@4.8.0-alpha.3
├─ @ember-data/private-build-infra@4.8.0-alpha.3
├─ @ember-data/record-data@4.8.0-alpha.3
├─ @ember-data/rfc395-data@0.0.4
├─ @ember-data/serializer@4.8.0-alpha.3
├─ @ember-data/store@4.8.0-alpha.3
├─ @ember-data/unpublished-test-infra@4.8.0-alpha.3
├─ babel-plugin-ember-data-packages-polyfill@0.1.2
├─ ember-data@4.8.0-alpha.3
└─ eslint-plugin-ember-data@4.8.0-alpha.3
Done in 0.62s.


Cheers!

@runspired
Copy link
Contributor

Probably the promise is chained incorrectly. I'll take a peek at it, sounds like it shouldn't be hard to create a reproduction test.

@law-rence
Copy link
Contributor Author

Yep, it should be easy to get a reproduction test done.

The data is stored in a database. I am not sure if it acts different if the data is stored inside the app. Just in case...if u need any help/information, let me know.

@runspired
Copy link
Contributor

@law-rence btw if you are in the discord hit me up, I'd love to keep in tighter touch with folks using canary builds <3

@runspired
Copy link
Contributor

So I looked into this and I'm not sure this is actually broken. At least, not when adding a test that mirrors what you've described.

I do notice that after the second call to findRecord, until that promise has resolved the proxy is null. Any chance you aren't awaiting a findRecord call somewhere and are eagerly accessing something on the promise proxy instead? (Or maybe accessing the proxy's content property?)

runspired added a commit that referenced this issue Aug 16, 2022
@law-rence
Copy link
Contributor Author

@runspired Yes, since the latest issue I opened up an account in discord.

I have done some more tests and will provide you the results here:

TEST CODE

    /**
     * Task to find a record..
     * @access  public
     * @return  {Void}
     */
    @task({
        maxConcurrency: 1,
        keepLatest: true,
    })
    *callFindRecord() {
        let result = undefined;
        let delay = 0;

        console.log(result);

        // first findRecord call
        console.log("first call");
        result = yield this.store.findRecord("tile", "388e9f019f93110e18efa386876b8f42").then((foundRecord) => {
            return foundRecord;
        });

        console.log(result);

        yield timeout(delay);

        // second findRecord call
        console.log("second call");
        result = yield this.store.findRecord("tile", "388e9f019f93110e18efa386876b8f42").then((foundRecord) => {
            return foundRecord;
        });

        console.log(result);

        yield timeout(delay);

        // third findRecord call
        console.log("third call");
        result = yield this.store.findRecord("tile", "388e9f019f93110e18efa386876b8f42").then((foundRecord) => {
            return foundRecord;
        });

        console.log(result);

        yield timeout(delay);

        // fourth findRecord call
        console.log("fourth call");
        result = yield this.store.findRecord("tile", "388e9f019f93110e18efa386876b8f42").then((foundRecord) => {
            return foundRecord;
        });

        console.log(result);
    }

Every time the task callFindRecord was called only one time.

RESULTS

  1. I have tried to call findRecord four times WITHOUT a delay between the calls -> let delay = 0
    The result is an error on the third call ^^.

image

  1. I have done the same like before BUT now I am waiting 1000 ms between the calls. The result is quiet different...
    -> let delay = 1000

image

Here it does not throw the error but the result stays null at any time.

To get around with that behaviour I have written a task that always calls peekRecord first (if findRecord with option reload is not desired) before calling findRecord.

    /**
     * Task to find a record..
     * @access  public
     * @return  {Void}
     */
    @task({
        maxConcurrency: 1,
        keepLatest: true,
    })
    *callFindRecord() {
        let result = undefined;
        let delay = 0;

        console.log(result);

        // first findRecord call
        console.log("first call");
        result = yield this.flexDataServices.performFindRecord.perform("tile", "388e9f019f93110e18efa386876b8f42");

        console.log(result);

        yield timeout(delay);

        // second findRecord call
        console.log("second call");
        result = yield this.flexDataServices.performFindRecord.perform("tile", "388e9f019f93110e18efa386876b8f42");

        console.log(result);

        yield timeout(delay);

        // third findRecord call
        console.log("third call");
        result = yield this.flexDataServices.performFindRecord.perform("tile", "388e9f019f93110e18efa386876b8f42");

        console.log(result);

        yield timeout(delay);

        // fourth findRecord call
        console.log("fourth call");
        result = yield this.flexDataServices.performFindRecord.perform("tile", "388e9f019f93110e18efa386876b8f42");

        console.log(result);
    }

Tests conditions like before.

image

image

  1. and 2. are presenting the same results (:

Current conclusion: Calling peekRecord first and on its result = null calling findRecord right after it.

@runspired
Copy link
Contributor

Is your adapter configured to background reload records?

law-rence added a commit to law-rence/ember-data that referenced this issue Aug 17, 2022
runspired added a commit that referenced this issue Aug 18, 2022
runspired added a commit that referenced this issue Aug 18, 2022
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 a pull request may close this issue.

2 participants