ReeceM/h-bar

Cannot read properties of undefined (reading 'linkWrapper')

Closed this issue · 9 comments

Hi,

Thanks for the project, trying it out gives an error:
Cannot read properties of undefined (reading 'linkWrapper')

Describe the bug
A clear and concise description of what the bug is.

To Reproduce


<script src="https://cdn.jsdelivr.net/npm/@reecem/h-bar@latest/dist/hBar.min.js"></script>
<script>
    hBar.init({
        link: "The link url, can be force and no need to fetch from API",
        title: "The link title goes here",

        url: "https://api.github.com/repos/ReeceM/h-bar/releases",
        parser: (data) => {
            // getting the first release on the list of releases from github.
            const { name, html_url } = data[0]
            console.log("hbar parser html_url", html_url)

            return {
                title: `Lateset version available ${name}`,
                link: html_url
            }
        },

        secondaryLinks: [
            {
                title: "Docs",
                link: "http:://docs.example.com"
            },
            {
                title: "Support",
                link: "http://help.example.com"
            }
        ],
        options: {
            theme: "blue",
        }
    })

    hBar.fetchData()
</script>

Could you please also publish the 2.0 version? Maybe it's fixed there.

Hi there,

That does seem to be an issue, coming from the init function and assigning the theme option.

What I could suggest is maybe give the version 2 one a test and let me know. I'll be happy to release that.

The below snippet is the way to use the new version. This is from the documentation site, it does make use of DOMPurify for example.

<!-- This code here should be near the top, it is the target element. It also tells it which template to use. -->
<div id="h-bar" style="position: -webkit-sticky; position: sticky; top: 0;" data-template="#hbar_template"></div>


    <script src="//cdn.jsdelivr.net/npm/dompurify@2.0.11/dist/purify.min.js"></script>
    <script src="//cdn.jsdelivr.net/npm/@reecem/h-bar@next/dist/hBar.min.js"></script>

<!-- This is where you define the html template to use for the h-bar -->
    <template id="hbar_template">
        <div class="flex w-full flex-col md:flex-row text-sm py-2 md:px-20 px-1 items-center justify-between bg-indigo-400 text-indigo-900">
            <div class="flex items-center mb-1 md:mb-0">
                <span class="px-2 mx-2 leading-relaxed tracking-wider uppercase font-semibold rounded-full text-xs bg-indigo-100 text-indigo-900 shadow">
                    Release
                </span>
                <a class="hover:underline inline-flex items-center hover:text-indigo-100" href="{% link %}" target="_blank">
                    {% title %}
                    <svg class="h-3 w-3" viewBox="0 0 20 20" fill="currentColor">
                        <path fill-rule="evenodd"
                            d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
                            clip-rule="evenodd"></path>
                    </svg>
                </a>
            </div>
            <div class="flex items-center">
                <a class="mx-5 cursor-pointer hover:underline hover:text-indigo-100" href="https://twitter.com/iexistin3d">@iexistin3d</a>
            </div>
        </div>
    </template>

    <script>
        hBar.init({
            el: "#h-bar",
            DOMPurify: DOMPurify,
            url: "https://api.github.com/repos/ReeceM/h-bar/releases",
            onCompleted: (e) => {
                console.log(e)
            },
            parser: (data) => {
                const {name, html_url} = data[0];
                return {
                    title: `Latest version available ${name}`,
                    link: html_url + '?ref=hbar_docs'
                };
            },
        })
        hBar.fetch()
    </script>

Hi & thanks for the quick reply,

Yes, it works now, although the result isn't pretty :) probably because of the template:
Screenshot from 2022-12-21 09-38-12

Would be good to have v2 published, with a simple getting started example such as

Screenshot from 2022-12-21 09-46-30

What would be useful, IMHO:

  • a close button (which would close that annoucement, but show others if a different text)
  • no deps (no DOMPurify)
  • be able to take a JSON as content, instead of an URL. The JSON could be loaded from URL in an example, but it would be more versatile to let users supply content from a CMS, from example.

Thank you!

Yeah so the version 2 one allows a person to add custom styling when they provide the template, if they don't it should fallback to the packages predefined Banner pattern.

What would be useful, IMHO:

  • a close button (which would close that annoucement, but show others if a different text)
  • no deps (no DOMPurify)
  • be able to take a JSON as content, instead of an URL. The JSON could be loaded from URL in an example, but it would be more versatile to let users supply content from a CMS, from example.

For those it is possible to run the package without DOMPurify, it is only needed when you supply a template as it writes the HTML content and it was provided as a way to ensure there wasn't possible XSS or stored XSS.

The close button showing for a different text doesn't work like that at the moment, but it is there to add dismissable notifications.

To use it with JSON is possible, if I understand you correctly, the original code came from a need to display data from the Wordpress wp-json endpoint. So that is supported as a default parser. Any other formats that come through you define a custom handler for that too

Example of just a simple setup. You can define the theme colour option. When using the template like the previous one you can use anything for the css styling.

<div
  id="h-bar"
  style="position: -webkit-sticky; position: sticky; top: 0"
></div>

<script src="//cdn.jsdelivr.net/npm/@reecem/h-bar@next/dist/hBar.min.js"></script>

<script>
  hBar.init({
    /** Note this part, this is the same as the theme section on the docs */
    theme: "red",

    el: "#h-bar",
    url: "https://api.github.com/repos/ReeceM/h-bar/releases",
    onCompleted: (e) => {
      console.log(e);
    },
    parser: (data) => {
      const { name, html_url } = data[0];
      return {
        title: `Latest version available ${name}`,
        link: html_url + "?ref=hbar_docs",
      };
    },
  });
  hBar.fetch();
</script>

Thanks for clarifications!

To use it with JSON is possible, if I understand you correctly, the original code came from a need to display data from the Wordpress wp-json endpoint. So that is supported as a default parser. Any other formats that come through you define a custom handler for that too

When using this on another platform, the data might be already there from other sources (my situation). Rather than make another API call to url, I propose having another parameter, eg announcements, which would have the content as returned by the API, eg

announcements: [
{
"url": "https://api.github.com/repos/ReeceM/h-bar/releases/27306040",
"assets_url": "https://api.github.com/repos/ReeceM/h-bar/releases/27306040/assets",
"upload_url": "[https://uploads.github.com/repos/ReeceM/h-bar/releases/27306040/assets{?name,label}](https://uploads.github.com/repos/ReeceM/h-bar/releases/27306040/assets%7B?name,label})",
"html_url": "https://github.com/ReeceM/h-bar/releases/tag/2.0.0-rc1",
"id": 27306040,
"author": {
...

One could set either announcements or url in the init() call. If announcements is set, just skip fetching content from URL and proceed with next step, probably parser.

This extents the usability of this library to many other cases, rather than being forced to load content from an URL.

Thanks for clarifications!

To use it with JSON is possible, if I understand you correctly, the original code came from a need to display data from the Wordpress wp-json endpoint. So that is supported as a default parser. Any other formats that come through you define a custom handler for that too

When using this on another platform, the data might be already there from other sources (my situation). Rather than make another API call to url, I propose having another parameter, eg announcements, which would have the content as returned by the API, eg

announcements: [
{
"url": "https://api.github.com/repos/ReeceM/h-bar/releases/27306040",
"assets_url": "https://api.github.com/repos/ReeceM/h-bar/releases/27306040/assets",
"upload_url": "[https://uploads.github.com/repos/ReeceM/h-bar/releases/27306040/assets{?name,label}](https://uploads.github.com/repos/ReeceM/h-bar/releases/27306040/assets%7B?name,label})",
"html_url": "https://github.com/ReeceM/h-bar/releases/tag/2.0.0-rc1",
"id": 27306040,
"author": {
...

One could set either announcements or url in the init() call. If announcements is set, just skip fetching content from URL and proceed with next step, probably parser.

This extents the usability of this library to many other cases, rather than being forced to load content from an URL.

Ohh, right, now I'm on the same page.

That does seem possible to add that in. I will have a look at that being added in 2.0 then as it would be nice to use it as a fallback option too if a URL doesn't load properly too.

Thank you, Reece!

I think all notes here are now in other separate issues. Should this be closed?

Yes, they are being tracked in the other ones 👍