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

Add modifier defer to control deferring storage #3463

Closed
wants to merge 5 commits into from

Conversation

hirasso
Copy link

@hirasso hirasso commented Mar 14, 2023

The persist plugin right now stores the value immediately on initialization. This prevents me from being able to use it in quite a few cases, where nothing should be stored in the browser before user interaction (GDPR compliance).

This PR attempts to solve this problem by adding a new modifier $persist('my-value').defer() that will wait for the first mutation of the data before storing it in the browser.

In my (manual) tests, it's already working fine for primitives, but for arrays and objects there seems to be something I'm missing (cypress tests are failing for arrays/objects right now).

If anyone from the maintainers thinks this could be a useful feature, I would be very grateful if they could have a look at why this fails with arrays. (Something inside Alpine.effect(), I guess...)

Actually, I'll add a failing test for arrays, so that it's easier for you guys.

@hirasso
Copy link
Author

hirasso commented Mar 14, 2023

Maybe a pointer to a solution with the failing array test: It passes if I use concat instead of push.

This fails:

test.only('can defer persisting an array',
    [html`
        <div x-data="{ things: $persist(['foo', 'bar']).defer() }">
            <button @click="things.push('baz')"></button>

            <span x-text="things.join('-')"></span>
        </div>
    `],
    ({ get }, reload) => {
        get('span').should(haveText('foo-bar'))
        get('button').click()
        get('span').should(haveText('foo-bar-baz'))
        reload()
        get('span').should(haveText('foo-bar-baz'))
    },
)

This passses:

test.only('can defer persisting an array',
    [html`
        <div x-data="{ things: $persist(['foo', 'bar']).defer() }">
            <button @click="things = things.concat(['baz'])"></button>

            <span x-text="things.join('-')"></span>
        </div>
    `],
    ({ get }, reload) => {
        get('span').should(haveText('foo-bar'))
        get('button').click()
        get('span').should(haveText('foo-bar-baz'))
        reload()
        get('span').should(haveText('foo-bar-baz'))
    },
)

Maybe this is somehow related to #383 ? The confusing part is that it works just fine with arrays and no .defer() modifier...

@ekwoka
Copy link
Contributor

ekwoka commented Mar 14, 2023

I think it should really just be the base behavior honestly.

Im curious how you're preventing the changes before getting GDPR approval?

Also, GDPR doesn't prevent storing data that is necessary for the application to work.

@hirasso
Copy link
Author

hirasso commented Mar 14, 2023

That's exactly the thing. Strictly speaking, storing the data before mutating it is not technically necessary.

In my opionion, the behavior introduced here should be the default behavior. I only added the modifier to make it opt-in and prevent breaking changes (consumers might already rely on the local storage entry being present from the beginning...)

What do you think?

@hirasso
Copy link
Author

hirasso commented Mar 14, 2023

You are right - it wouldn't be possible to get the user's permission before persisting the value right now. I'll close this. Anyways, nice little exercise for the history plugin :)

@hirasso hirasso closed this Mar 14, 2023
@hirasso hirasso deleted the feature/persist-ignore-initial branch March 14, 2023 16:57
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