coderello / laravel-shared-data

📦 An easy way to share the data from your backend to the JavaScript.
https://coderello.com/docs/laravel-shared-data/1.0/sharing-data
MIT License
321 stars 22 forks source link

improve to prevent re assign window var #15

Closed j574144 closed 4 years ago

j574144 commented 4 years ago

Hi

As first thing I want congrat you for this package, this is very useful.

Deeping more, the window variable should not allow to change in client side (unless necessary). With this current render the windows var can set to new value window.sharedData.username = 'new user'.

My recommendation is to change the render function or maybe add new function as renderInmmutable() as like:

public function renderInmmutable(): string
    {

        return '<script>window[\''.$this->getJsNamespace().'\'] =  (() => {

            let output = '.$this->toJson().';

            return { 
                data () {
                return output;
              }
            }
          })();</script>';
    }

Then youcan call it as: window.sharedData.data()

I appreciate your attention and feedback

hivokas commented 4 years ago

Hi @j574144,

Thanks for your interest!

I've been thinking about this issue (especially how to avoid breaking changes). Here is my draft:

Object.defineProperty(
  window,
  'sharedData', {
    get: function () {
      return { user: 5, role: { id: 3 } } ;
    },
  }
);

console.log(JSON.stringify(window.sharedData));

window.sharedData.role.id = 1;

window.sharedData = 2;

delete window.sharedData;

console.log(JSON.stringify(window.sharedData));

Your thoughts?

hivokas commented 4 years ago

You have a little typo in your example.

In your case you'll need to call window.sharedData().data(), not window.sharedData.data().

hivokas commented 4 years ago

Your example could by bypassed by a few lines of code.

// your example
window.sharedData = (() => {
    return {
        data() {
            return { user: 5, role: { id: 3 } };
        }
    };
});

// bypassing
var changedData = window.sharedData().data();

changedData.user = 1;

window.sharedData = (() => {
    return {
        data() {
            return changedData;
        }
    };
});

console.log(JSON.stringify(window.sharedData().data()));
j574144 commented 4 years ago

Hi @hivokas

All responses from you are great for me. I think that Object.defineProperty is good approach. I start to use it from now.

Thanks