Components in Vue are not reflecting changes to reactive properties when using composition

I'm currently in the process of developing a notification system, and while it's partially functional, there are some issues. Here is the Composition function I am using:

const data = reactive({
    notifications: []
});
let notificationKey = 0;

export const useNotification = () => {
    const visibleNotifications = computed(() => {
        return data.notifications.slice().reverse();
    });

    const add = (notification: INotification) => {
        notification.key  = notificationKey++;
        notification.type = notification.type ?? 'success';

        notification.icon      = iconObject[notification.type];
        notification.iconColor = iconColorObject[notification.type];
        data.notifications.push(notification);

        notificationTimer[notification.key] = new Timer(() => {
            remove(notification.key);
        }, notificationTimeout);
    };

    const remove = (notificationKey: number) => {
        const notificationIndex = data.notifications.findIndex(notification => notification?.key === notificationKey);
        if (notificationTimer[notificationKey] !== undefined) {
            notificationTimer[notificationKey].stop();
        }
        if (notificationIndex > -1) {
            data.notifications.splice(notificationIndex, 1);
        }
    };

    const click = (notification: INotification) => {
       /// ... click code 
    };

    return {
        visibleNotifications,
        add,
        remove,
        click
    };
};

The functionality described above is operational (albeit slightly simplified). Moving on to the entry points in Webpack, one being "auth", where the following code loads a Vue Component for displaying notifications

 Promise.all([
    import(/* webpackChunkName: "Vue"*/ 'vue'),
    import(/* webpackChunkName: "@vue/composition-api"*/ '@vue/composition-api'),
    import(/* webpackChunkName: "Notifications"*/'components/Notifications.vue')
]).then((
    [
        { default: Vue },
        { default: VueCompositionAPI },
        { default: Notifications },
    ]) => {
    Vue.use(VueCompositionAPI);

    new Vue({
        render: h => h(Notifications)
    }).$mount('.notification-outer);
});

The mentioned setup works well when integrating the code below

import { useNotification } from 'modules/compositionFunctions/notifications';
useNotification().add({
    title  : 'Error',
    message: 'This is an error notification',
    type   : 'error',
});

Once executed, the notification is displayed as intendedhttps://i.sstatic.net/8zMPg.png. All these actions occur within the "auth" entry point and involve TypeScript.

On the other hand, the second entry point in "editor" requires additional implementation within an existing JS file:

import(/* webpackChunkName: "useNotification"*/ 'modules/compositionFunctions/notifications').then(({ useNotification }) => {
    useNotification().add({
        title     : 'Block Deleted',
        message   : 'The block has been deleted',
        buttonText: 'Undo',
        buttonFunction () {
            undoDelete();
        }
    });
});

Although this code functions properly with all features from the useNotification function operating correctly, the changes are not reflected in the Vue component. While logging the reactive property showcases the expected behavior, the Vue component fails to acknowledge these alterations when triggered from the "editor" entry point.

Vue Component JS

import { useNotification } from 'modules/compositionFunctions/notifications';
import { defineComponent } from '@vue/composition-api';

export default defineComponent({
    name : 'Notifications',
    setup () {
        const { visibleNotifications, remove, click: notificationClick } = useNotification();

        return {
            visibleNotifications,
            remove,
            notificationClick,
        };
    },
    watch: {
        visibleNotifications: (v) => {
            console.log(v);
        }
    }
});

If anyone can assist, please step forward. This situation is really testing my patience...

Thanks in advance

Answer №1

After incorporating the code from the GitHub repository, I included additional console logging right before this section:

window.alerts = reactive({
   alerts: []
});

The logging occurred twice - once from bundle1.js and again from bundle2.js.

My knowledge of Webpack is somewhat limited, but it appears that these two entry-points are designed to be independent and not meant to run simultaneously on a single page.

I would have expected the notification functionality to be extracted into its own shared chunk, similar to the vendors bundle. However, I am puzzled as to why there are two separate entry-points instead of utilizing chunks. Typically, entry-points are assigned one per page with further segmentation achieved through chunks.

To address this issue temporarily, you can implement a quick fix:

if (!window.alerts) {
    window.alerts = reactive({
        alerts: []
    });
}

This approach ensures that the same array is shared regardless of how many times it is executed.

Please note that using such a workaround in production code is not recommended. It may postpone the Webpack-related challenges while cluttering the global namespace. Nonetheless, it can assist in identifying the root cause of the problem.

Answer №2

After reviewing your code, it seems that your components are tightly interconnected. I recommend adopting a more object-oriented approach such as user->data->notification->seen and so forth. This may require some restructuring of your current codebase and possibly your database structure.

I also suggest considering Firebase (FCM - Firebase Cloud Messaging) for a notification system. Firebase is a product by Google, known for its reliable methodology in implementing scalable notification systems.

However, if you prefer not to rely on third-party services and have a self-developed app, an alternative method would be using the "notify on change" approach.

Here is a basic outline:

  • An event occurs in the database/app that requires user notification
  • Determine the scope of the event and its impact on users
  • Create a notifier object (e.g., notif.json) stored either in the database or as plain JSON
  • Send notifications to active users when they are online

You can track user activity using setInterval() on the client side and deliver pending notifications from notif.json once they are active. Remember, don't hesitate to try a different approach if the current one is not yielding results; sometimes starting fresh with a new perspective can save time in the long run.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Struggling to generate distinct charts with chart.js

I need assistance in displaying individual charts for different sensors on a web page. Currently, when multiple SensorData is selected by the user, it generates a single "multi chart" which is not the desired outcome. Below is the code snippet responsible ...

Incorrect embeds are dispatched when removing messages per user and term

Recently, I've been delving into the world of JavaScript to develop a custom Purge Command. I took inspiration from a Purge Command written in TypeScript by reconlx for their DJS v13 command handler, and with some tweaks, I managed to make it compatib ...

Is there a way to filter and tally the JSON objects that have latitude and longitude within a 10km radius from the

I'm currently working on filtering and counting objects from an API endpoint that fall within a 10km radius of the specified origin. My main challenge lies in correctly filtering the API results and tallying the number of matching items. While I succ ...

Add an event listener to a dynamically created div block through jQuery when it is clicked

When the page loads, a dynamic div appears that is visible to the user and in Firebug, but is not available in the page source. The content within this div changes dynamically. I am attempting to bind a click event to this div so that when a user clicks o ...

Applying reduce method for accessing object information within an array and transforming its structure

In my data structure, I have a list of deliveries that includes different cities and the number of units delivered to each city: var deliveries = [{ location: "Chicago", units: 10 }, { location: "San Francisco", units: 5 }, { location: ...

What is the best way to retrieve the initial cell from a row that the user is currently hovering over?

Is there a way to extract the first cell from a row when a user hovers over it and then clicks a specific key combination? (considering using jQuery) I have a table set up similarly where placing the mouse over a tr and pressing ctrl+c will copy the ID t ...

What is causing the data not to react with the props in this particular scenario?

In addition to the central App.vue component, I have two other components - Rooms.vue and Desks.vue. When a swiper element in the Rooms.vue component is clicked, it triggers the opening of the Desks.vue component and emits the room object to App.vue. This ...

Improved Node.js algorithm designed to identify anagrams of a specific string in an array. The approach must not rely on generating all possible subsets to find the anagram of the string

I am looking to create a collection of anagram pairs within an array. The input will consist of the initial array of strings. For example: let inputArray = ["abcd", "dbac", "adfs", "adsf", "bDca"]; This program should consider the case of the letters, m ...

Capture the Vue slot's HTML content and store it in a variable

Is it possible to achieve something similar to this: <div id="app"> <div class="container"> <h1 class="title is-1" v-html="text"></h1> <get-slot-contents> <p>Hi there</p> <p>Hi <span ...

Retrieve the HTTP response code from an Ajax request within a PhantomJS website interaction

Our team is utilizing PhantomJS to capture a screenshot of our company's internal website. The script we are using is similar to the official examples provided by PhantomJS, but with an additional variable called waitTime (https://github.com/ariya/p ...

Revamp the code by implementing promises

Upon calling the code snippet below, the two Webtrends calls are getting cancelled instead of returning an HTTP 200 status. This happens because the form submission triggers the cancellation. To resolve this issue, I introduced a 2-second delay before subm ...

Unleashing the power of DOM events through jQuery observables

I'm a bit confused at the moment. I'm working with an Angular project using a Bootstrap theme. Someone has implemented tab functionality using Bootstrap, but there's an issue - it's all written in JavaScript. This means that events such ...

Discover the country's three-letter code with the power of HTML and Javascript!

I am in search of a way to determine the location of a user based on the country they are browsing from. I want to achieve this using HTML and Javascript. While researching on stackoverflow, I came across various suggestions to use different API's for ...

WebStorm failing to identify Node.js functions

I recently began my journey in learning node.js and I'm currently utilizing WebStorm 11 as my preferred IDE. However, I've encountered an issue where WebStorm does not seem to recognize the writeHead method: var http = require("http"); http.cre ...

Exploring the contrast between router.pathname and router.route within Next.js

Essentially, my goal is to utilize the NextJS router to access the page url by doing the following: import { useRouter } from "next/router"; const SomeComp = props => { const router = useRouter(); } Yet, when I console.log() the propertie ...

Issues encountered with certain Tailwind styles functioning improperly when deployed in a production environment with Next.js

It seems that there are some style issues occurring in the production build hosted on Netlify for a specific component. The problematic component is a wrapper located at ./layout/FormLayout.tsx. Below is the code for this wrapper: const FormLayout: React.F ...

What methods are available to modify styles for the before and after pseudo-elements in Angular?

I'm currently in the process of adding breadcrumb navigation with triangle shapes using before/after elements in CSS, following the method outlined in this tutorial: http://css-tricks.com/triangle-breadcrumbs/ These are the relevant code snippets: ...

How can I call the telerik radgrid.databind() function using a JavaScript function?

Currently, I am coding in ASP .NET and have an ASPX page featuring a Telerik RadGrid. I am curious to know if it is feasible to call the RadGrid.DataBind() method from within a JavaScript function? ...

What is the best way to programmatically disable a button in JavaScript or jQuery when all the checkboxes in a grid are either disabled or unchecked?

In my grid, one column contains checkboxes. I need to implement a feature where a button is disabled if all the checkboxes are unticked. How can I achieve this using JavaScript or jQuery? .Aspx File <asp:TemplateField HeaderText="Cancel SO Line Item"& ...

How does gray-matter function in Node.js affect the matter within?

import fs from 'fs'; import path from 'path'; import matter from 'gray-matter'; const postsDirectory = path.join(process.cwd(), 'posts'); // ... ... ... // export function getPostData(id) { const fullPath = ...