TypeError: u.then is not a function in Vue3+Vue router

Console Error

TypeError: u.then is not a function
    at index-CyodobdF.js:26:14273
    at Object.runWithContext (index-CyodobdF.js:14:10931)
    at we (index-CyodobdF.js:26:19934)
    at index-CyodobdF.js:26:23018

index-CyodobdF.js

function W(x, F, L) {
        Be(x);
        const k = ie.list();
        return k.length ? k.forEach(ee => ee(x, F, L)) : console.error(x), // here
        Promise.reject(x)
    }

It worked fine when running locally using ‘npm run dev’, but after deploying ‘npm run build’ using nginx, the following error occurs. After logging in as below link, an error occurs during the redirect operation using router(). I tried to solve it using the answers in the link, but in my case, it didn’t work much. Can you check if there is a problem with my router?

Also, I think there may be a problem with the code because we rushed to develop without knowing about Vue3.

/router/index.js


import { createRouter, createWebHistory } from 'vue-router'
import Marker from '@/assets/icon/filled/marker.svg'
import Book from '@/assets/icon/filled/book.svg'
import User from '@/assets/icon/filled/user.svg'
import CloseRec from '@/assets/icon/filled/close-rectangle.svg'
import Cookies from 'js-cookie'
import { logoutUser } from '@/lib/utils.js'

const router = createRouter({
    history: createWebHistory(import.meta.env.BASE_URL),
    routes: [
        {
            path: '/auth',
            component: () => import('../views/Layouts/AuthLayout.jsx'),
            redirect: '/auth/login',
            children: [
                {
                    path: 'login',
                    component: () => import('@/views/pages/LoginView.jsx'),
                    meta: {}
                },
                {
                    path: 'join',
                    component: () => import('@/views/pages/JoinView.jsx'),
                    meta: {}
                }
            ]
        },
        {
            path: '/diary',
            component: () => import('../views/Layouts/MainLayout.jsx'),
            redirect: '/diary/list',
            children: [
                {
                    path: 'list',
                    component: () => import('@/views/pages/MyDiaryView.jsx'),
                    meta: {
                        is_show: true,
                        title: '내 일기',
                        icon: Book, 
                        requiresAuth: true
                    }
                },
                {
                    path: 'write',
                    component: () => import('@/views/pages/WriteView.jsx'),
                    meta: {
                        is_show: true,
                        title: '일기 쓰기',
                        icon: Marker, 
                        requiresAuth: true
                    }
                },
                {
                    path: 'detail/:id',
                    component: () => import('@/views/pages/DetailView.jsx'),
                    meta: {
                        is_show: false,
                        title: '내 일기',
                        icon: Book, 
                        requiresAuth: true
                    }
                }
            ]
        },
        {
            path: '/account',
            component: () => import('../views/Layouts/MainLayout.jsx'),
            children: [
                {
                    path: 'info',
                    component: () => import('@/views/pages/AccountInfoView.jsx'),
                    meta: {
                        is_show: true,
                        title: '내 정보',
                        icon: User, 
                        requiresAuth: true
                    }
                },
                {
                    path: 'logout',
                    component: () => import('@/views/pages/LogoutView.jsx'),
                    beforeEnter: async (to, from, next) => {
                        try {
                            await logoutUser() 
                            next('/auth/login')
                        } catch (error) {
                            console.error('로그아웃 중 에러 발생:', error)
                            next('/auth/login') 
                        }
                    },
                    meta: {
                        is_show: true,
                        title: '로그아웃',
                        icon: CloseRec,
                        requiresAuth: true
                    }
                }
            ]
        }
    ]
})


router.beforeEach((to, from, next) => {
    const isLoggedIn = !!Cookies.get('is_login')

    if (to.path === '/') {
        next(isLoggedIn ? '/diary/list' : '/auth/login')
    } else if (to.meta.requiresAuth && !isLoggedIn) {
        Cookies.remove('is_login')
        next('/auth/login')
    } else {
        next()
    }
})

export default router

how to configure webpack to exclude certain modules from a library?

I have a React app that imports a library (in the node_modules directory, of course).

The name of the library is @lib/schema.

In the react app, modules of this library are imported like so:

import { module_name } from "@lib/schema"

There is a certain file in the @lib/schema that is currently being included in the final bundle, which is located in this path:

src/path/to/large_file.js

The file is never used by the app and thus unnecessarily increases the size of the bundle.

The React app currently uses react-scripts to create the bundle.

Questions:

  1. If the React app were to continue to use react-scripts, how to configure it to exclude src/path/to/large_file.js?
  2. If the React app were to use webpack, how to configure it to exclude src/path/to/large_file.js?

Safari shows black screen using getUserMedia and MediaRecorder (works fine in Chrome)

I’m building a React component to record a video testimonial using the browser’s camera and microphone. The same code works in Chrome (works on chrome desktop but not moibile) Safari (macOS/iOS) shows a black screen during the live preview.
Behavior:

I call navigator.mediaDevices.getUserMedia({ video: true, audio: true }).
Console logs confirm that Safari returns an active MediaStream with a valid “FaceTime HD Camera” track.
The element is set to srcObject = stream. Despite that, the remains black on Safari while recording.
Once I stop the recording, the recorded video blob actually plays back fine (or sometimes that also appears black—depends on the code approach).

What I Tried:

Setting playsinline, webkit-playsinline, autoplay, and muted before assigning video.srcObject.
Using an onloadedmetadata handler with a short setTimeout before calling video.play():

javascriptCopyvideo.onloadedmetadata = () => {
    setTimeout(() => {
        video.play().catch(err => console.error(err));
    }, 100);
};

Ensuring I only stop camera tracks in my resetRecording() (after the user’s done), rather than immediately in stopRecording().
Confirmed Safari’s Auto-Play settings in System Preferences → Websites → Auto-Play. Even tried “Allow All Auto-Play.”
Verified I’m serving the site over HTTPS / localhost.
Ensured I’m not calling track.stop() or reassigning the same from srcObject to a blob too early.
Added forced dimensions and a hardware-acceleration nudge:

cssCopyvideo {
    width: 640px;
    height: 360px;
    transform: translate3d(0, 0, 0);
}

Checked the Safari console for errors—no explicit “NotAllowedError” or “autoplay blocked” message appears.

Below is the shortened version of my React code that should illustrate what I’m doing. (Full code is about the same, just with additional UI and submission logic.)
typescriptCopy’use client’;

import React, { useState, useRef, useEffect } from 'react';

export function VideoRecorder() {
    const [recordingState, setRecordingState] = useState<'initial'|'countdown'|'recording'|'review'>('initial');
    const videoRef = useRef<HTMLVideoElement>(null);
    const streamRef = useRef<MediaStream|null>(null);

    const checkPermissions = async () => {
        try {
            const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
            console.log('Stream:', stream, 'Tracks:', stream.getVideoTracks());
            streamRef.current = stream;
            setRecordingState('countdown');

            await new Promise(requestAnimationFrame);

            if (videoRef.current) {
                videoRef.current.setAttribute('playsinline', 'true');
                videoRef.current.setAttribute('webkit-playsinline', 'true');
                videoRef.current.autoplay = true;
                videoRef.current.muted = true;
                videoRef.current.srcObject = stream;

                videoRef.current.onloadedmetadata = () => {
                    setTimeout(() => {
                        videoRef.current?.play().catch(err => console.error('play() failed:', err));
                    }, 100);
                };
            }
        } catch (err) {
            console.error('Permissions error:', err);
        }
    };

    const startRecording = () => {
        // ...
    };

    const stopRecording = () => {
        // ...
    };

    return (
        <div>
            {recordingState === 'initial' && (
                <button onClick={checkPermissions}>
                    Start
                </button>
            )}
            {(recordingState === 'countdown' || recordingState === 'recording' || recordingState === 'review') && (
                <video ref={videoRef} playsInline muted />
            )}
            {/* More code for countdown, etc... */}
        </div>
    );
}

I’ve tried every trick I know for Safari autoplay:

Muted, playsinline, webkit-playsinline
A user gesture triggers getUserMedia()
I’m not stopping the track too soon
My code runs on HTTPS
Safari Dev Tools show no autoplay error, just a black screen

Question: Why is Safari still showing a black screen even though the video track is active and the same code works in Chrome? Are there any additional Safari-specific constraints or settings that could cause a black screen with a valid media track?

Does JavaScript garbage collection delete parent objects if sub object is still in scope?

If I have an object that contains 2 sub-objects, and I delete the pointers to the parent object and one of the child objects, but I still have a pointer to the other child object, will JavaScript delete the one child and the parent, or will the whole parent object remain even though it’s no longer addressable?

I know I could use delete to remove the other child element, but that still leaves the parent. And I want to understand GC better and whether this explicit cleanup is necessary.

var parentObj = {
    A: { subObjA: 'data' },
    B: { subObjB: 'data' }
};

var persist = parentObj.B;
parentObj = null;

After this, will the parent object and subObjA be deleted since they are no longer accessible. or will the whole object remain because I have a pointer to subObjB?

Javascript: How to inspect an iterator object (iterator protocol)?

I’m trying to understand what’s inside an iterator object.

Q: How can I see every property/method of an object, in this case an iteration object?
How can I see exactly of what an object is made of?
Why is the .next() method not listed by the Object.getOwnPropertyNames() method?
I thought that every method in an object needs to be attached to a key inside that object?
The only keys that show up are the ones(color, taste) I added myself.

Below the html code and the rendered page:

<!DOCTYPE html>
<html>
<body>

<h1>JavaScript Strings</h1>
<h2>The matchAll() Method</h2>

<p>ES2020 intoduced the string method matchAll().</p>

<p id="demo"></p>


<script>
let text = "I love cats. Cats are very easy to love. Cats are very popular."
const iterator = text.matchAll(/Cats/gi);

// If I can add a properties, then it must be an object.
iterator.color = "green";
iterator.taste = "salty";

let text2 = "<hr>";
text2 += "Iterator object entries => ";
for (let [key, value] of Object.entries(iterator)) {
  text2 += key + ": " + value + ", ";
}
text2 += "<br><br>";

text2 += "Print out the iterator object directly => " + iterator + "<br><br>";
text2 += "Iterator object keys => " + Object.keys(iterator) + "<br><br>";
text2 += "Iterator object values => " + Object.values(iterator) + "<br><br>";
text2 += "Stringified JSON => " + JSON.stringify(iterator) + "<br><br>";
text2 += "Object.getOwnPropertyNames(iterator) => " + Object.getOwnPropertyNames(iterator) + "<br><br>";

// Intentionally calling .next() Method to "consume" one iteration.
iterator.next();
text2 += "Array.from(iterator) => " + Array.from(iterator) + "<br>";
document.getElementById("demo").innerHTML = text2; 


</script>

</body>
</html>

The rendered page looks something like this:

JavaScript Strings
The matchAll() Method

ES2020 intoduced the string method matchAll().

Iterator object entries => color: green, taste: salty,

Print out the iterator object directly => [object RegExp String Iterator]

Iterator object keys => color,taste

Iterator object values => green,salty

Stringified JSON => {"color":"green","taste":"salty"}

Object.getOwnPropertyNames(iterator) => color,taste

Array.from(iterator) => Cats,Cats

iterator Protocol

W3Schools string.matchAll

choosen example

HIghlight feature not working on chrome extension

I’m working on building a Chrome extension that highlights preselected chemicals on a webpage. However, when I activate the extension, it doesn’t highlight them in blue as I specified in the code. Please advise on what is going on, and why my program does not automatically highlight the chemicals on the webpage.

Content.js file

  1: {
    English: ["Coconut butter"],
    Japanese: ["ココナッツバター"],
    Korean: ["코코넛 버터"]
  },
  2: {
    English: ["Coconut oil"],
    Japanese: ["ココナッツオイル"],
    Korean: ["코코넛 오일"]
  },
  3: {
    English: ["talc"],
    Japanese: ["タルク"],
    Korean: ["활석"]
  },
  4: {
    English: ["mica"],
    Japanese: ["雲母"],
    Korean: ["운모"]
  },
  5: {
    English: ["alcohol"],
    Japanese: ["アルコール"],
    Korean: ["술"]
  }
};

let activeHighlights = [];

function highlightText(matches) {
  matches.forEach((match) => {
    const span = document.createElement("span");
    span.className = "highlight";
    span.textContent = match.textContent;
    match.replaceWith(span);
    activeHighlights.push(span);
  });
}

chrome.runtime.onMessage.addListener((message) => {
  if (message.type === "highlight") {
    clearHighlights();
    const { levels, languages, customTerm } = message.data;

    const regexParts = [];
    levels.forEach((level) => {
      languages.forEach((lang) => {
        if (chemicals[level][lang]) {
          regexParts.push(...chemicals[level][lang]);
        }
      });
    });

    if (customTerm) regexParts.push(customTerm);

    const regex = new RegExp(`\b(${regexParts.join("|")})\b`, "gi");
    const matches = Array.from(document.body.querySelectorAll("*:not(script):not(style)"))
      .flatMap((node) => Array.from(node.childNodes).filter((child) => child.nodeType === 3))
      .filter((node) => regex.test(node.textContent));

    highlightText(matches);
  }

  if (message.type === "clear") {
    clearHighlights();
  }
});

function clearHighlights() {
  activeHighlights.forEach((span) => {
    const textNode = document.createTextNode(span.textContent);
    span.replaceWith(textNode);
  });
  activeHighlights = [];
}

Style.css

  font-family: Arial, sans-serif;
}

#container {
  text-align: center;
  padding: 10px;
}

button {
  margin: 5px;
  padding: 10px;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}

button.selected {
  background-color: #007bff;
  color: white;
}

button.off {
  background-color: #ccc;
  color: #666;
}

#activateButton {
  background-color: #007bff;
  color: white;
}

#activateButton.active {
  background-color: #28a745;
}

.highlight {
  background-color: blue;
  color: white;
  font-weight: bold;
}

Unexpected ‘xmlns’ attribute in serialized XML

I’m trying to generate XSPF (XML) in JavaScript, and display the generated code in a <pre> block on a webpage. This is for a web app that creates music playlists.

screenshot of web app

This is the JS code I’m currently experimenting with:

    const xspfTemplate = `<?xml version="1.0" encoding="UTF-8"?>
<playlist version="1" xmlns="http://xspf.org/ns/0/">
    <trackList>
    </trackList>
</playlist>`;
    const parser = new DOMParser();
    const serializer = new XMLSerializer();
    xspfDoc = parser.parseFromString(xspfTemplate, 'text/xml');

    let track = xspfDoc.createElement('track');
    let location = xspfDoc.createElement('location');
    location.textContent = encodeURIComponent('my album/my music.mp3');
    track.append(location);
    xspfDoc.querySelector('trackList').append(track);

    let xspfString = serializer.serializeToString(xspfDoc);
    xspfOutput.append(xspfString);

After investigating with the Firefox debugger, it appears to me that the serialization step is adding an empty xmlns attribute to the <track> element.

Actual output:

<?xml version="1.0" encoding="UTF-8"?>
<playlist version="1" xmlns="http://xspf.org/ns/0/">
    <trackList>
    <track xmlns=""><location>my%20album%2Fmy%20music.mp3</location></track></trackList>
</playlist>

Expected output:

<?xml version="1.0" encoding="UTF-8"?>
<playlist version="1" xmlns="http://xspf.org/ns/0/">
    <trackList>
    <track><location>my%20album%2Fmy%20music.mp3</location></track></trackList>
</playlist>

My reference for handling XML in JavaScript

Cookies not sent with request when using iframe for login in Angular

I have two applications:

Auth: Handles authentication (Sign-in/Sign-up, etc.)

Main: The main application

Both applications are served under the same domain:

Main: example.com

Auth: example.com/auth

In the main app, if the user is not logged in, they can click a login button. This opens a login screen in a popup using an iframe, which loads the login page from the Auth project.

When the login page is created, I send a request to the backend to check if there’s a valid token in the cookies. I rely on the browser to automatically include the token in the cookies, and on the backend, I validate it.

The issue is:

Inside the iframe, I can see the token in the cookies when I check with cookieService.get(“token”).
But the token is not sent with the request to the backend.
For example:

const token = cookieService.get("token"); // token is there
const { isValid } = await lastValueFrom(auth.validateJwtToken()); // token is NOT sent 
 // with the request

However, if I navigate to the login page directly using the URL (example.com/auth/login), the token is sent correctly with the request.

Why I’m Doing This:

I need to perform token validation on the Auth project because:

When a user opens two tabs and logs in from one tab, the other tab doesn’t update automatically.
The other tab still shows the login button, and the user can click it to log in again, which I want to prevent.

What could be causing the cookies to not be sent with requests from the iframe? How can I ensure the cookies are sent properly so that the backend can validate them, even inside an iframe?

Cant populating existing datatable es6+

Link to test case:
https://codepen.io/arcanisgk-the-sasster/pen/ZYzJqwG

static async updateTable(info) {

        console.log("DatatablePlugin.updateTable");
        
        const table = new $.fn.dataTable.Api(`${info.target}`);
        console.log({'table':table});

        table.clear();

        console.log({'info.content.data':info.content.data});
        table.rows.add(info.content.data);

        table.draw();
        table.columns.adjust();

    }

Code snippets not supported by Staged are not supported. I have used Codepen… to show a working example with issues…

Error messages shown:

DataTables warning: table id=translations-table – Requested unknown parameter ‘0’ for row 0, column 0. For more information about this error, please see https://datatables.net/tn/4

Description of problem:

Hi, I’m back to my last stage of development related to datatables, in this case, as I do it in the test case, I’m trying to populate an existing datatable from a single script or method, that’s why you can see that I’m trying to populate the table from a single static call to initialization and I’m not implementing Ajax.

In this case the problem has to do with the message, I am trying to clean the table in case it has previous data, and then I am trying to add new data, as well as make column adjustments if necessary… the problem is that the rows are added, but they do not have any data. As you can see I have created a Json/object structure that simulates the data.

The only thing I can think of is that I need to define the columns, in the initialization, so that in the update, you recognize where each piece of data should go… but I simply don’t understand the error that appears… assuming that my json/object structure is correct.

I have tried to change the “updateTable” script

  • clone the current configuration.
  • destroy the table.
  • initialize it with the cloned data and configuration.

and with this new version i try the error disappears, but:

  • the configuration is not maintained
  • nor is the data displayed

updated code:

https://codepen.io/arcanisgk-the-sasster/pen/QwLMJdw

static async updateTable(info) {

        console.log("DatatablePlugin.updateTable");
        const jsonContent = typeof info.content.data === 'string' ? JSON.parse(info.content.data) : info.content.data;

        const target = $(`${info.target}`);
        const table = target.DataTable();
        const currentConfig = table.init();

        table.destroy();

        return target.DataTable({
            ...currentConfig.oInit,
            data: jsonContent.data
        });

    }

The existing post does not work in my implementation:

https://stackoverflow.com/a/62281831/28825980

how to pass array data to existing jquery datatable

Sequelize update query resulting in error

I’m running into an issue where querying my database for an update is returning an error in my express app using sequelize. I have the following code in my controller:

I’m seeing the following error in the console:

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

I’ve tried adding async to the anonymous function being assigned to activateChecklist and await to Checklist.update but that did not change anything.

Is there a logical error in my code I am not seeing?

    Checklist.update(
      { active: false },
      { where: {} }
    )
    .then(() => {
      console.log('All checklists set to inactive');
    })
    .catch((err) => {
      console.log('activateChecklist RESULTED IN AN ERROR: ' . err);
    });
    //activate clicked on entry
    const id = req.params.id;
    Checklist.findByPk(id)
      .then((checklist) => {
      if (!checklist) {
        return res.status(404).send('Checklist not found');
      }
      return checklist.update({
        active: true,
      });
      })
      .then(() => {
      console.log('Checklist activated');
      res.redirect('/admin/all-checklists');
      })
      .catch((err) => {
      console.log('activateChecklist RESULTED IN AN ERROR: ' + err);
      res.status(500).send('Error activating checklist');
      });
  
  }```

Reading drop down lists and closing them with click

I’m making a browser extension reading data from the site. Currently I make reading a drop down list reading. Currently code looks like this:

const button = getDropDownListButton();
button.click();
readData();
const closer = getListCloserObject();
closer.click();

When i paste into the console code for closing this list it works, but not in extension. I know that click happens every time when in code called click() method. Lists open, i got data, but lists doesn’t close. And in some time it seems like 2 lists opened at one time (they close each other on click).
P.S. Site seems like uses compiled React code so i don’t know what happens on it, so i can’t provide an example
P.P.S. As i sayed, lists close all other on opening. So, if i delete list as html object opening other list results in error. On click list opener creates an object containing invisible div on the whole screen deleting on click all object created by list button

Smoothly transition SVG elements with the view transition API

I have the following problem: I am trying to move SVG elements with the view transition API smoothly from one position to the other by applying a view-transition-name. While this works perfectly for HTML elements for some reason only the default cross-fade animation is applied to SVG elements.

I have a simple demo here (unfortunately this only works in Chromium-based browsers at the moment): https://codesandbox.io/p/sandbox/svg-view-transition-test-2l5vnp

In that demo you see two elements: a circle rendered with SVG and a square rendered with HTML. When the SVG circle is clicked the default animation, the cross-fade, is applied. When the HTML square is clicked a smooth transition is performed. Both examples have more or less the same config: startViewTransition is called, the element is replaced with the same ID as before. Shouldn’t that smooth transition also work for SVG elements, am I doing something wrong in my demo or did I miss something?

I know that the smooth transition for SVGs can be achieved by customizing the animation with the web animations API for example, but I’d like to get that working with the view-transition-name only.

Thanks for your help!

How to make popup work correctly on photo gallery

The popup I made for each indiviual image on the photo gallery isn’t working at all.

I’ve tried re-arranging the button element and messing with the js code. Overall I think the issue may be in the css side of things. This is my first time posting on here.

function togglePopup() {
  document.getElementById("popup-1").classList.toggle("active");
}
.photo-gallery {
  width: 90%;
  margin: auto;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-gap: 20px;
}

.pic {
  margin-top: 130px;
  position: relative;
  height: 230px;
  border-radius: 10px;
  box-shadow: 3px 3px 5px lightgray;
  cursor: pointer;
}

.pic img {
  width: 100%;
  height: 100%;
  border-radius: 10px;
}

.website::before {
  content: "This website!";
  text-align: center;
}

.popup .overlay {
  position: fixed;
  top: 0px;
  left: 0px;
  width: 100vw;
  height: 100vh;
  background: rgba(0, 0, 0, 0.7);
  z-index: 1;
}

.popup {
  display: none;
}


.popup .content {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translateY(-50%, -50%);
  background: #fff;
  width: 450px;
  height: 220px;
  z-index: 2;
  text-align: center;
  padding: 20px;
  box-sizing: border-box;

}

.popup .close-btn {
  cursor: pointer;
  position: absolute;
  right: 20px;
  top: 20px;
  width: 30px;
  height: 30px;
  background: #222;
  color: #fff;
  font-size: 25px;
  font-weight: 600;
  line-height: 30px;
  text-align: center;
  border-radius: 50%;
}

.popup.active .overlay {
  display: block;
}

.popup.active .content {
  transition: all 300ms ease-in-out;
  transform: translate(-50%, -50%) scale(1);
}
<div class="photo-gallery">
  <div class="pic website">
    <button onclick="togglePopup()"><img src="https://i.ibb.co/W5RWrch/Screenshot-2024-12-24-194906.png" alt="Button Image"></button>
  </div>

  <div class="popup" id="popup-1">
    <div class="overlay"></div>
    <div class="content">
      <div class="close-btn">&times;</div>
      <h1>Title</h1>
      <p>weeeeeeeewooooooooooo</p>
    </div>
  </div>

React UI not re-rendering with state update

I’m trying to create an expenses track app using react JS. The problem is that I’m updating the state of the variable, but the UI doesn’t change accordingly. For each new expense added, the idea is that: a) if the expense name already exists, a new line is not created, instead, the value of the new expense is added to the existing value; b) if the expense name does not exist, a new expense line is created.

Logging to the console, I can see that for the case a) the variable groupedExpenses is updated, but the UI of the expense line isn’t updated.

Below is my code:

  1. App.jsx
import Expenses from "./components/Expenses";
import Form from "./components/Form";
import { useState } from "react";

function App() {
  const [groupedExpenses, setGroupedExpenses] = useState({});

  function addExpense(name, amount) {
    setGroupedExpenses((previousGroupedExpenses) => {
      let newGroupedExpenses = { ...previousGroupedExpenses };
      console.log(newGroupedExpenses);
      if (name in newGroupedExpenses) {
        newGroupedExpenses[name] += parseFloat(amount.replace(",", "."));
      } else {
        newGroupedExpenses[name] = parseFloat(amount.replace(",", "."));
      }
      return newGroupedExpenses;
    });
  }

  return (
    <div className="expensesapp stack-large">
      <h1>Expense Manager</h1>
      <Form addExpense={addExpense} />
      <Expenses groupedExpenses={groupedExpenses} />
    </div>
  );
}

export default App;

  1. Form.jsx
import { useState } from "react";

import TextField from "@mui/material/TextField";
import Stack from "@mui/material/Stack";
import Autocomplete from "@mui/material/Autocomplete";
import InputAdornment from "@mui/material/InputAdornment";
import Icon from "@mui/material/Icon";

function Form(props) {
  const [expenseName, setExpenseName] = useState("");
  const [expenseAmount, setExpenseAmount] = useState("");

  const [options, setOptions] = useState([]);

  function handleChangeName(event) {
    setExpenseName(event.target.value);
  }

  function handleSelectSuggestion(event, value) {
    setExpenseName(value);
  }

  function handleChangeAmount(event) {
    setExpenseAmount(event.target.value);
  }

  function handleSubmit(event) {
    event.preventDefault();
    props.addExpense(expenseName, expenseAmount);

    if (!options.includes(expenseName)) {
      setOptions([...options, expenseName]);
    }

    setExpenseName("");
    setExpenseAmount("");
  }

  return (
    <form onSubmit={handleSubmit}>
      <div className="expense">
        <Stack direction="row" spacing={1} sx={{ width: 300 }}>
          <Autocomplete
            sx={{ m: 1, width: "25ch" }}
            id="free-solo"
            freeSolo
            onInputChange={handleChangeName}
            onChange={handleSelectSuggestion}
            options={options}
            renderInput={(params) => (
              <TextField {...params} label="nome" value={expenseName} />
            )}
          />
          <TextField
            label="valor"
            id="outlined-start-adornment"
            sx={{ m: 1, width: "25ch" }}
            onChange={handleChangeAmount}
            value={expenseAmount}
            slotProps={{
              input: {
                startAdornment: (
                  <InputAdornment position="start">R$</InputAdornment>
                ),
              },
            }}
          />
          <button type="submit" className="btn btn__primary btn__lg">
            <Icon>add_circle</Icon>
          </button>
        </Stack>
      </div>
    </form>
  );
}

export default Form;
  1. Expenses.jsx
function Expenses(props) {
  console.log(props.groupedExpenses);

  return (
    <ul
      role="list"
      className="expenses-list stack-large stack-exception"
      aria-labelledby="list-heading"
    >
      {props.groupedExpenses !== undefined &&
        Object.entries(props.groupedExpenses).map(([k, v]) => (
          <div>
            <li className="expense stack-small">
              <input
                type="text"
                className="input input-name input__lg"
                name="name"
                autoComplete="off"
                defaultValue={k}
                readOnly
              />
              <input
                type="text"
                className="input input-value input__lg"
                name="value"
                autoComplete="off"
                defaultValue={v}
                readOnly
              />
            </li>
          </div>
        ))}
    </ul>
  );
}

export default Expenses;

Could anyone point out what am I doing wrong? Thanks!