DevExpress: TabPanel: Add a template dynamically in JavaScript

I am trying to dynamically populate a DevExpress tabpanel(dxTabPanel) with custom templates in my javascript code. Correct number of tabs are being added but the tab content is empty. How do I dynamically populate a Tab Panels’ template? In sample code below, there are 2 templates, employeeListTemplate and addEditEmployeeTemplate that have some content. They are not being displayed in my webpage.

@(Html.DevExtreme().Button().ID("addTabsButton").OnClick("populateTabPanel").Text("Add Tabs").Type(ButtonType.Default).Width(100))

@(
Html.DevExtreme().TabPanel()
.ID("contentTabPanel")
.Loop(false)
.AnimationEnabled(false)
.SwipeEnabled(false)
.DeferRendering(false)
.RepaintChangesOnly(false)
.ScrollingEnabled(true)
)

@using (Html.DevExtreme().NamedTemplate("employeeListTemplate"))
{    
    @(Html.DevExtreme().DataGrid()
            .Columns(c =>
            {
                c.Add().DataField("FirstName").AllowEditing(true);
                c.Add().DataField("LastName").AllowEditing(true);                
                c.Add().DataField("Address1").AllowEditing(true);
                c.Add().DataField("Address2").AllowEditing(true);
                c.Add().DataField("City").AllowEditing(true);
                c.Add().DataField("State").AllowEditing(true);
                c.Add().DataField("Zip").AllowEditing(true);
                c.Add().DataField("PhoneNumber").AllowEditing(true);
            })
        )
}

@using (Html.DevExtreme().NamedTemplate("addEditEmployeeTemplate"))
{
    <div>This is Admin->Add Edit Employee</div>
}

JavaScript:

var items = [];
function populateTabPanel() {

    let jsonString = '{"ParentID":1,"ParentName":"Administration","ID":1,"Text":"Employee","Icon":null,"Path":null,"Templates":[{"ID":1,"TemplateIndex":0,"TemplateName":"employeeListTemplate","IsVisible":true,"Title":"Current Employees"},{"ID":2,"TemplateIndex":1,"TemplateName":"addEditEmployeeTemplate","IsVisible":true,"Title":"Add/ Update Employee"}]} ';
    let tabPanelInstance = $("#contentTabPanel").dxTabPanel("instance");
    let tabPanelItems = tabPanelInstance.option('items');    
    items.length = 0;    
    var templateObj = JSON.parse(jsonString);    
    var templateArray = templateObj.Templates;    
    for (var i = 0; i < templateArray.length; i++) {
        items.push(
        {
            template: templateArray[i].TemplateName,
            title: templateArray[i].Title,
            index: templateArray[i].TemplateIndex
        }
        );
    }


    
    let tabPanelInstance = $("#contentTabPanel").dxTabPanel("instance");
    tabPanelInstance.option("items", items);
}



Host Static SPA written in HTML/JS in WebView2

I have created a Static SPA using SvelteKit, and i want to open the application in Revit using WebView2. The compiled file structure of my application looks like this:

build
- index.html
- favicon.png
- _app
  - env.js
  - version.json
  - immutable
    - chunks
      - disclose-version.BtJd_2Dd.js
      - entry.D6WgGb8s.js
      - proxy.C4KmojzZ.js
      - render.zjJFQd9i.js
      - runtime.4rquTwgo.js
    - entry
      - app.Cc30Kppw.js
      - start.BjQAhHL7.js
    - nodes
      - 0.rlw-XIZ8.js
      - 1.BWC29Vl1.js
      - 2.CteRqxFd.js

And my index.html file looks like this:

<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <link rel="icon" href="/favicon.png" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        
        <link rel="modulepreload" href="/_app/immutable/entry/start.BjQAhHL7.js">
        <link rel="modulepreload" href="/_app/immutable/chunks/entry.D6WgGb8s.js">
        <link rel="modulepreload" href="/_app/immutable/chunks/runtime.4rquTwgo.js">
        <link rel="modulepreload" href="/_app/immutable/entry/app.Cc30Kppw.js">
        <link rel="modulepreload" href="/_app/immutable/chunks/render.zjJFQd9i.js">
        <link rel="modulepreload" href="/_app/immutable/chunks/disclose-version.BtJd_2Dd.js">
        <link rel="modulepreload" href="/_app/immutable/chunks/proxy.C4KmojzZ.js">
    </head>
    <body data-sveltekit-preload-data="hover">
        <div style="display: contents">
            <script>
                {
                    __sveltekit_v04hc = {
                        base: ""
                    };

                    const element = document.currentScript.parentElement;

                    Promise.all([
                        import("/_app/immutable/entry/start.BjQAhHL7.js"),
                        import("/_app/immutable/entry/app.Cc30Kppw.js")
                    ]).then(([kit, app]) => {
                        kit.start(app, element);
                    });
                }
            </script>
        </div>
    </body>
</html>

I have tried to host the application using npx serve and this works flawlessly.

Now i try to host it through WebView2. I write the following C# code:

webView.CoreWebView2.SetVirtualHostNameToFolderMapping(
    "app.revitfoundry",
    "C:\path\to\my\app\build",
    CoreWebView2HostResourceAccessKind.Allow
);

webView.Source = new Uri("https://app.revitfoundry/index.html");

When loading the web view, the application loads, but my application cannot find the index.html file:

Could not find /index.html

When inspecting the webview, all the files within the HTML/JS application are loaded into “Sources” and are stored in top->app.revitfoundry. Even the index.html file is stored here, which the application seems not to be able to find.

What could cause the error? Is it something with Svelte? If so, then i find it weird that the code works when running a server using npx serve. Is it maybe something wrong with the configurations of the webView?

Better way to check an object

I have an object that I request with Redux-Toolkit Query. Inside that object I have a property which I use to decide whether to show modal or not. I would like to rewrite the way I check it. Are there any suggestions? I don’t like using ? too much and I think it could be done differently. I use useEffect because I need open/setOpen state hardcoded on initial render so the app won’t throw errors. The modal is a Material-UI component.

import { Box, Modal } from "@mui/material";
import { getUserId } from "helpers/localstoragehelper";
import { useEffect, useState } from "react";
import { useGetUserQuery } from "../../redux/api/userApiSlice";
import TermsTabs from "./TermsTabs";

const TermsModal = ({ children }) => {
  const { data } = useGetUserQuery(getUserId());

  const [open, setOpen] = useState(false);
  const handleClose = () => setOpen(false);

  useEffect(() => {
    if (data?.isTermsApprovalRequired) setOpen(true);
  }, [data?.isTermsApprovalRequired]);

  return (
    <>
      {children}
      <Modal
        open={open}
        onClose={handleClose}
        aria-labelledby="modal-modal-title"
        aria-describedby="modal-modal-description"
        sx={(theme) => ({
          color: "white",
          zIndex: theme.zIndex.drawer + 1,
        })}
      >
        <Box>
          <TermsTabs handleClose={handleClose} />
        </Box>
      </Modal>
    </>
  );
};

export default TermsModal;

Issue with Interaction Next.js 14 Server Calling API and Passing Data to Component

I am using the Next.js App Router architecture, and I have a post page that calls an API and passes the data to a component. I have already implemented simple interactions like clicking to change some styles, etc. However, how can I implement more complex features, such as clicking a button to fetch data again or adding/deleting/updating post? Since I am directly mapping the post data, I can’t change the state. I tried storing the post data in useState within useEffect and then mapping through the data in useState, but this loses the SSR effect, and the view-source ends up being empty.

How should I achieve this? Is it possible to sync server data into the initial component? Can the server data be stored globally? Or what should I search for to solve my problem?

// post page

"use client"
import PostItem from "./components/PostItem"
import { useState } from "react"

export default function PostPage() {
    const [activeId, setActiveId] = useState(0)

    // Assuming it’s data from the API
    const post = [
        {
            id: 101,
            title: "How to Learn JavaScript",
            content: "JavaScript is a versatile language...",
            author: "john_doe",
            created_at: "2024-10-01T10:20:30Z",
            tags: ["javascript", "programming", "tutorial"],
        },
        {
            id: 102,
            title: "Understanding CSS Grid",
            content: "CSS Grid is a powerful layout system...",
            author: "jane_smith",
            created_at: "2024-09-28T14:15:22Z",
            tags: ["css", "frontend", "web design"],
        },
        {
            id: 103,
            title: "Introduction to React",
            content: "React is a popular JavaScript library...",
            author: "mark_twain",
            created_at: "2024-08-22T08:45:12Z",
            tags: ["react", "javascript", "frontend"],
        },
    ]

    console.log({ post })

    return (
        <div className="flex flex-wrap gap-2 mt-4 justify-center items-center">
            {post.map((p) => {
                return (
                    <PostItem
                        key={p.id}
                        {...p}
                        onClick={() => setActiveId(p.id)}
                        isActive={activeId === p.id}
                    />
                )
            })}
        </div>
    )
}

// post item component
interface PostItemProps {
    id: number
    title: string
    content: string
    author: string
    created_at: string
    tags: Array<string>
    isActive?: boolean
    onClick: () => void
}

export default function PostItem(props: PostItemProps) {
    const { id, title, content, author, created_at, tags, isActive, onClick } =
        props

    return (
        <section
            className={`transition-all duration-500 cursor-pointer w-[200px] p-4 ${
                isActive
                    ? "bg-blue-700 text-yellow-200 rounded-lg"
                    : "bg-blue-600 text-white"
            } `}
            onClick={onClick}
        >
            <div className="text-xl font-bold mb-2">{title}</div>
            <div className="mb-2">{content}</div>
            <ul className="mb-2">
                {tags.map((t, index) => {
                    return <li key={index}>{t}</li>
                })}
            </ul>
        </section>
    )
}

I tried SSR data passing to components for interaction, but I’m not sure of the correct approach.

401 Unauthorized Error When Fetching Data from Chrome Extension to Backend Hosted on Vercel

I’m building a Chrome extension that needs to fetch data from Wiktionary.
Due to CORS restrictions, I can’t directly make requests from the Chrome extension to Wiktionary. Therefore, I want to use a proxy backend hosted on Vercel to handle these requests and send the data back to the extension.
Here’s my current server.js for the backend:

const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const fetch = require('node-fetch'); 
const app = express();
const PORT = process.env.PORT || 3000;

// Allow CORS for my Chrome extension
app.use(cors({
  origin: ['chrome-extension://my-extension-id'], 
  methods: ['GET', 'POST', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization'],
}));

app.use(bodyParser.json());
app.use(express.static('public'));

// Health check route
app.get('/', (req, res) => {
  res.send('mainpage');
});

// Proxy route to fetch data from Wiktionary
app.get('/proxy/:word', async (req, res) => {
  const word = req.params.word
    .replaceAll('ō', 'o')
    .replaceAll('ā', 'a')
    .replaceAll('ī', 'i')
    .replaceAll('ū', 'u');
  try {
    const response = await fetch(`https://en.wiktionary.org/wiki/${word}`);
    if (!response.ok) {
      throw new Error('Failed to fetch data from Wiktionary');
    }
    const text = await response.text(); 
    res.send(text); 
    console.log(`Successfully fetched data for word: ${word}`);
  } catch (error) {
    console.error('Error fetching from Wiktionary:', error);
    res.status(500).send('Error fetching from Wiktionary');
  }
});

// Start the server
app.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});

Here is the frontend code piece that uses the backend

fetch(`https://myappbackendurlexample.vercel.app/fetch/${word}`)
          .then(response => response.text())
          .then(html => {
            const parser = new DOMParser();
            const baseDoc = parser.parseFromString(html, 'text/html');
            //following implementations
          })

And my manifest.json

{
//related fields
  "manifest_version": 3,
  "permissions": ["storage","https://myappbackendurlexample.vercel.app/*"],
  "host_permissions": ["https://myappbackendurlexample.vercel.app/*"],
  "content_security_policy": {
    "script-src": "'self'",
    "object-src": "'self'"
  },
  "background": {
    "service_worker": "server.js"
  }
  
}

However, even though my backend can get the data from wiktionary successfully, my frontend always has
these errors, as the backend probably doesnt let the front end visit.

Access to fetch at ‘https://myappbackendurlexample.vercel.app/fetch/gestarum’ from origin ‘chrome-extension://extension_ID’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.Understand this error
myappbackendurlexample.vercel.app/fetch/gestarum:1

Failed to load resource: net::ERR_FAILEDUnderstand this error
Inflections.js:17

Uncaught (in promise) TypeError: Failed to fetch
at HTMLButtonElement. (Inflections.js:17:9)

Since chrome extension does not allow node,I tried to fetch the data directly and add wikitionary to permissions and host_permissions. I published this version seperately and its still in review so I am trying to use this local version and vercel backend.
I also tried setting up a proxy route in my Express server to forward requests to wiktionayr but doesnt really work.
I checked the logs on Vercel but did not find any additional information explaining the 401 Unauthorized error.
As running the code on localhost works fine,I expected that the Chrome extension would be able to make successful fetch requests to my backend (hosted on Vercel), which would in turn fetch data from Wiktionary and return it to the extension.

401 Unauthorized Error When Fetching Data from Chrome Extension to Backend Hosted on Vercel

I’m building a Chrome extension that needs to fetch data from Wiktionary.
Due to CORS restrictions, I can’t directly make requests from the Chrome extension to Wiktionary. Therefore, I want to use a proxy backend hosted on Vercel to handle these requests and send the data back to the extension.
Here’s my current server.js for the backend:

const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const fetch = require('node-fetch'); 
const app = express();
const PORT = process.env.PORT || 3000;

// Allow CORS for my Chrome extension
app.use(cors({
  origin: ['chrome-extension://my-extension-id'], 
  methods: ['GET', 'POST', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization'],
}));

app.use(bodyParser.json());
app.use(express.static('public'));

// Health check route
app.get('/', (req, res) => {
  res.send('mainpage');
});

// Proxy route to fetch data from Wiktionary
app.get('/proxy/:word', async (req, res) => {
  const word = req.params.word
    .replaceAll('ō', 'o')
    .replaceAll('ā', 'a')
    .replaceAll('ī', 'i')
    .replaceAll('ū', 'u');
  try {
    const response = await fetch(`https://en.wiktionary.org/wiki/${word}`);
    if (!response.ok) {
      throw new Error('Failed to fetch data from Wiktionary');
    }
    const text = await response.text(); 
    res.send(text); 
    console.log(`Successfully fetched data for word: ${word}`);
  } catch (error) {
    console.error('Error fetching from Wiktionary:', error);
    res.status(500).send('Error fetching from Wiktionary');
  }
});

// Start the server
app.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});

Here is the frontend code piece that uses the backend

fetch(`https://myappbackendurlexample.vercel.app/fetch/${word}`)
          .then(response => response.text())
          .then(html => {
            const parser = new DOMParser();
            const baseDoc = parser.parseFromString(html, 'text/html');
            //following implementations
          })

And my manifest.json

{
//related fields
  "manifest_version": 3,
  "permissions": ["storage","https://myappbackendurlexample.vercel.app/*"],
  "host_permissions": ["https://myappbackendurlexample.vercel.app/*"],
  "content_security_policy": {
    "script-src": "'self'",
    "object-src": "'self'"
  },
  "background": {
    "service_worker": "server.js"
  }
  
}

However, even though my backend can get the data from wiktionary successfully, my frontend always has
these errors, as the backend probably doesnt let the front end visit.

Access to fetch at ‘https://myappbackendurlexample.vercel.app/fetch/gestarum’ from origin ‘chrome-extension://extension_ID’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.Understand this error
myappbackendurlexample.vercel.app/fetch/gestarum:1

Failed to load resource: net::ERR_FAILEDUnderstand this error
Inflections.js:17

Uncaught (in promise) TypeError: Failed to fetch
at HTMLButtonElement. (Inflections.js:17:9)

Since chrome extension does not allow node,I tried to fetch the data directly and add wikitionary to permissions and host_permissions. I published this version seperately and its still in review so I am trying to use this local version and vercel backend.
I also tried setting up a proxy route in my Express server to forward requests to wiktionayr but doesnt really work.
I checked the logs on Vercel but did not find any additional information explaining the 401 Unauthorized error.
As running the code on localhost works fine,I expected that the Chrome extension would be able to make successful fetch requests to my backend (hosted on Vercel), which would in turn fetch data from Wiktionary and return it to the extension.

vite public compile confusion

const imageList = [
    "Wildcard.png",
    "Diamonds.png",
    "Hearts.png",
    "Spades.png",
    "Clubs.png"
].map((v) => new URL(`/img/${v}`, import.meta.url).href);

Why is this not equivalent to this?
The first one yields /example-project/assets/undefined
The second one yields the correct one /example-project/img/Wildcard.png

const imageList = [
    new URL("/img/Wildcard.png", import.meta.url).href,
    new URL("/img/Diamonds.png", import.meta.url).href,
    new URL("/img/Hearts.png", import.meta.url).href,
    new URL("/img/Spades.png", import.meta.url).href,
    new URL("/img/Clubs.png", import.meta.url).href,
];

In some rare cases, the first one can yields /src/components/undefined with the use of a function that behaves almost exactly like that map callback but instead of an arrow function it is an actual function declaration. The base on vite.config.js is set correctly to the repo name for Github-Pages deployment.

I don’t know if I’m a bit misguided on where static assets lived, or some side-effects I forgot to take a count of, or **there’s something seriously wrong with how I compile / build the app with Vite. **

I am thoroughly confused and wished to gain some more insight on this.

vite public compile confusion

const imageList = [
    "Wildcard.png",
    "Diamonds.png",
    "Hearts.png",
    "Spades.png",
    "Clubs.png"
].map((v) => new URL(`/img/${v}`, import.meta.url).href);

Why is this not equivalent to this?
The first one yields /example-project/assets/undefined
The second one yields the correct one /example-project/img/Wildcard.png

const imageList = [
    new URL("/img/Wildcard.png", import.meta.url).href,
    new URL("/img/Diamonds.png", import.meta.url).href,
    new URL("/img/Hearts.png", import.meta.url).href,
    new URL("/img/Spades.png", import.meta.url).href,
    new URL("/img/Clubs.png", import.meta.url).href,
];

In some rare cases, the first one can yields /src/components/undefined with the use of a function that behaves almost exactly like that map callback but instead of an arrow function it is an actual function declaration. The base on vite.config.js is set correctly to the repo name for Github-Pages deployment.

I don’t know if I’m a bit misguided on where static assets lived, or some side-effects I forgot to take a count of, or **there’s something seriously wrong with how I compile / build the app with Vite. **

I am thoroughly confused and wished to gain some more insight on this.

Injecting input fields into existing HTML Form

Im trying to make a form which will be adding a new inputs whenever the user fill another input. I set up an event listener that will do ajax request into my back-end and, if succeed, it will bring an element of input that will be injected into the form. it looked like this :

            $.ajax({
                type: "GET",
                url: "{% url 'cart:get-delivery' %}",
                data :{
                    city : id
                },
                success: function(res) {
                    $("#delivery").replaceWith(res.component)
                    $('.spinner-overlay').remove();
                },
                error: function(e) {
                    console.log("Failed")
                    $('.spinner-overlay').remove();
                }
            })

the form works on the surface, but when I submit the form, it won’t recognize my newly added input fields. so when I do request.POST.get(‘example’) it won’t appear. does anyone have solution on this? also here is the added element :

{% load humanize %}
{% if content %}
<td id="delivery">
    {% for ins in content %}
        {% for jenis in ins.costs %}
        <div class="form-check">
            <input class="form-check-input" type="radio" name="radio-delivery" id="{{ins.code}}" value="{{jenis.cost.0.value}}|{{ins.code}}|{{jenis.service}}">
            <label class="form-check-label" for="radio-delivery">
            <strong>{{ins.code | upper}}</strong> - {{jenis.service}} : Rp {{jenis.cost.0.value | intcomma}}
            </label>
        </div>
      {% endfor %}
    {% endfor %}
</td>
{% endif %}

Injecting input fields into existing HTML Form

Im trying to make a form which will be adding a new inputs whenever the user fill another input. I set up an event listener that will do ajax request into my back-end and, if succeed, it will bring an element of input that will be injected into the form. it looked like this :

            $.ajax({
                type: "GET",
                url: "{% url 'cart:get-delivery' %}",
                data :{
                    city : id
                },
                success: function(res) {
                    $("#delivery").replaceWith(res.component)
                    $('.spinner-overlay').remove();
                },
                error: function(e) {
                    console.log("Failed")
                    $('.spinner-overlay').remove();
                }
            })

the form works on the surface, but when I submit the form, it won’t recognize my newly added input fields. so when I do request.POST.get(‘example’) it won’t appear. does anyone have solution on this? also here is the added element :

{% load humanize %}
{% if content %}
<td id="delivery">
    {% for ins in content %}
        {% for jenis in ins.costs %}
        <div class="form-check">
            <input class="form-check-input" type="radio" name="radio-delivery" id="{{ins.code}}" value="{{jenis.cost.0.value}}|{{ins.code}}|{{jenis.service}}">
            <label class="form-check-label" for="radio-delivery">
            <strong>{{ins.code | upper}}</strong> - {{jenis.service}} : Rp {{jenis.cost.0.value | intcomma}}
            </label>
        </div>
      {% endfor %}
    {% endfor %}
</td>
{% endif %}

Django Issue After Migration: Identical Code in Test and Main Branch, But Production Fails

Has anyone encountered a similar issue in Django? In my test branch, everything works fine, including the password reset functionality. However, in production, it throws an error stating that the page doesn’t exist (even though it’s definitely there).

I’m also experiencing a similar issue with date formatting. In test branch, the date displays correctly as the current month and year, but in production, it shows a different value, like “September 2020.” Any ideas on what could be causing this?

I’ve reviewed the code in both the main and test branches, and everything appears identical. The issue began after the most recent migration, even though the site isn’t used very often.

Also if you will be wondering for some reason DEBUG = True And it’s output specifically for the passwords was that the template was not found as I told you earlier.

Any help would be highly appreciated!

Django Issue After Migration: Identical Code in Test and Main Branch, But Production Fails

Has anyone encountered a similar issue in Django? In my test branch, everything works fine, including the password reset functionality. However, in production, it throws an error stating that the page doesn’t exist (even though it’s definitely there).

I’m also experiencing a similar issue with date formatting. In test branch, the date displays correctly as the current month and year, but in production, it shows a different value, like “September 2020.” Any ideas on what could be causing this?

I’ve reviewed the code in both the main and test branches, and everything appears identical. The issue began after the most recent migration, even though the site isn’t used very often.

Also if you will be wondering for some reason DEBUG = True And it’s output specifically for the passwords was that the template was not found as I told you earlier.

Any help would be highly appreciated!

Having to use setTimeout even after awaiting nextTick?

I am trying to watch a computed value that gets filled up with messages from a store. This is it (code reduced for brevity):

<div ref="RefWindow">
<!-- Messages shown here -->
</div>


const Feed = computed(() => MyStore.Messages)
const RefWindow = ref();

function scrollToBottom() {
      console.log(`scrollTop: ${RefWindow.value.scrollTop}, scrollHeight: ${RefWindow.value.scrollHeight}`)
      RefWindow.value.scrollTop = RefWindow.value.scrollHeight; // Scrolls to bottom
    }

 watch(() => Feed, async () => {
      await nextTick();
    
      scrollToBottom(); // Doesn't work console.log shows scrollTop: 0, scrollHeight: 0
 
      setTimeout(()=> scrollToBottom(), 20); // Works console.log shows scrollTop: 0, scrollHeight: 4203
      }
    }, {
      immediate: true,
      deep: true
    })

It was my understanding that nextTick() is almost like onUpdated lifecycle hook in that once Feed‘s value has changed, on the next update of the DOM the code should run. However without the setTimeout in place it seems the scrollHeight of the div RefWindow is not being updated.

What is the correct way to go about this without using a timeout?

Having to use setTimeout even after awaiting nextTick?

I am trying to watch a computed value that gets filled up with messages from a store. This is it (code reduced for brevity):

<div ref="RefWindow">
<!-- Messages shown here -->
</div>


const Feed = computed(() => MyStore.Messages)
const RefWindow = ref();

function scrollToBottom() {
      console.log(`scrollTop: ${RefWindow.value.scrollTop}, scrollHeight: ${RefWindow.value.scrollHeight}`)
      RefWindow.value.scrollTop = RefWindow.value.scrollHeight; // Scrolls to bottom
    }

 watch(() => Feed, async () => {
      await nextTick();
    
      scrollToBottom(); // Doesn't work console.log shows scrollTop: 0, scrollHeight: 0
 
      setTimeout(()=> scrollToBottom(), 20); // Works console.log shows scrollTop: 0, scrollHeight: 4203
      }
    }, {
      immediate: true,
      deep: true
    })

It was my understanding that nextTick() is almost like onUpdated lifecycle hook in that once Feed‘s value has changed, on the next update of the DOM the code should run. However without the setTimeout in place it seems the scrollHeight of the div RefWindow is not being updated.

What is the correct way to go about this without using a timeout?

How to enable sorting with Datagrid in Highcharts?

The docs on highcharts.com do not agree with the docs on api.highcharts.com. Two things jump out at me:

  1. The HTML used is div‘s not table/tr/td
  2. The column options described are completely different

(Also the links to the “API Reference” from the main webpage go to 404’s.)

The API docs appear to be the correct ones but unfortunately they don’t include the cool sorting options. So my question then is: how do I enable sorting in a Highcharts DataGrid or where can I find an example?

differences between api docs and main website