Skip to content
This repository has been archived by the owner on Dec 5, 2022. It is now read-only.

what is the best way to pass data to fragments ? #292

Open
yury-kozlov opened this issue Mar 3, 2019 · 13 comments
Open

what is the best way to pass data to fragments ? #292

yury-kozlov opened this issue Mar 3, 2019 · 13 comments

Comments

@yury-kozlov
Copy link

yury-kozlov commented Mar 3, 2019

Hi, we are doing a poc with tailor and trying to initialize fragments with some input data.
Here's a simple example:

  • user sends request to index.html?language=1
  • we configure tailor to forward query-string parameters as http headers to all fragments
  • each fragment receives language and saves it in window.STATE object
  • when fragment's script is executed in the browser, the state is initialized, and html is rendered according to the language
    The main problem here is that window.STATE can be overwritten by other fragments (although we can solve this by giving unique names)

Do you have any working alternatives besides this approach ?

@stevoPerisic
Copy link

Since the fragments are considered micro-services they should be stateless. I suggest having only one service that manages state. Which one it is will depend on what kind of application you are developing.

Regarding passing data to fragments the only way is through the headers as you have already implemented.

@yury-kozlov
Copy link
Author

yury-kozlov commented Mar 3, 2019

I suggest having only one service that manages state

If we have one service (=fragment) to manage the state, is it possible to make it loaded first in the browser ?

@stevoPerisic
Copy link

If you add the attribute "primary" to your fragment this will be the main fragment that determines of the page responds with a 200 or not. It won't necessarily be the first fragment but you can make sure that the rest of the front-end processing doesn't start until this fragment is done loading.
There are front-end hooks that you can use for this as well. https://github.com/zalando/tailor/blob/master/docs/hooks.md
I've successfully used these to wait for the state manager to finish processing and than start the rest of the dependent logic.
One more way to communicate between the fragments are the custom DOM events if you don't want to use the Tailor hooks.

@yury-kozlov
Copy link
Author

I thought "primary" attribute is only for resolving status code and location of the original request.
I want to implement a common fragment with shared dependencies, including global state manager (for example Redux). The order of loading here is very important.
How can I use front-end hooks to make sure all fragments are executed after this common fragment is loaded and initialized ?
Do I need to implement some deferred logic in each fragment script that will depend on Pipe.onAfterInit event ?

@stevoPerisic
Copy link

stevoPerisic commented Mar 3, 2019 via email

@delueg
Copy link

delueg commented Nov 18, 2019

As i want to do something similar. Can you tell me how is it possible to access the headers in the template?

@yury-kozlov
Copy link
Author

As i want to do something similar. Can you tell me how is it possible to access the headers in the template?

Not completely understood your question. If it's node.js code, then simply call request.headers and make sure you pass them in filterRequestHeaders() function because Tailor blocks all headers except default ones: https://github.com/zalando/tailor/blob/master/lib/filter-headers.js.

@delueg
Copy link

delueg commented Nov 18, 2019

Hello thank you for your reply. I want to access headers in my template file to conditional loading a script based on the headers value like

templates/layout.pug


if headers.myheader === 'true'
  script(type="script" scr="3rd/party/absolut/url")

@yury-kozlov
Copy link
Author

I'm not familiar with pug engine. Generally, if it runs as a middleware, you should have access to the current request and headers are part of request/response.

@delueg
Copy link

delueg commented Nov 18, 2019

How would you access the request in a "plain" HTML Template?

@yury-kozlov
Copy link
Author

yury-kozlov commented Nov 18, 2019

If your template is generated on the fly, then I guess you are on the server and you should have access to the request (again, I'm not familiar with pug). If it's a static HTML, then you may use window global variables. Those vars you may initialize on server-side (inside a response returned from fragment), but due to the order of loading need to make sure fragment scripts are evaluated on client before those template scripts.

@delueg
Copy link

delueg commented Nov 18, 2019

Thanks, that helped for general understanding!

@vigneshshanmugam
Copy link
Collaborator

vigneshshanmugam commented Nov 19, 2019

There is another way to do this, If you are the one controlling tailor. You can use handleTag functionality to do something similar.

function handleTag (request, tag) {
   const feature = request.headers && request.headers['feature'];
   if (feature) {
      return `<script src="" ></script>`
   }
   return ''
}

The feature can also be tuned using tags. Assuming if there is a custom element present on the template and that would help enable/disable a specific feature.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants