React Library Project: Unable to import a file (has no default export)

I am creating my first react library. I am using vite to build the project. I was writing a sample demo file (in the same root folder) to illustrate how it works when I noticed that when I import the main file to consume it I get the following error,

Module '"/Users/<user>/workspaces/<project-name>/src/mainFile.tsx"' has no default export

But I am using the default export. Here is the code for the mainFile.tsx,

/* eslint-disable @typescript-eslint/no-explicit-any */
import React from "react";

const TestFunction = ({ path }: { path: string }) => {
  console.log(`path`, path);
  return <div>{path}</div>;
};

export default TestFunction;

Here is the code for the sample demo file.tsx,

import React from "react";
import ReactDOM from "react-dom";
import TestFunction from "./mainFile";

const App = () => (
  <div>
    <h1>Testing My Library</h1>
    <TestFunction path="./sample.json" />
  </div>
);

ReactDOM.render(<App />, document.getElementById("root"));

To buid the project I am using,

"build": "tsc && vite build"

and project type is set as module,

"type": "module",

Can someone please point me in the right direction? thanks

How to curve a number in canvas

I’m doing a test of a billiards game in 2D canvas, but I can’t curve the numbers on the balls, I can rotate and shrink them, but I’m not able to bend them, by bending them I mean like the human back, which is not completely straight , but it has a curve, when a number is in the corners of the ball from the center where you look at the ball, the number should be curved, but I can’t find the answer to achieve that.

Not receiving push notifications on ios from firebase messaging

I have followed all the steps that were needed to perform on apple developer account and firebase messaging but still not getting notifications on IOS. I am sending notifications through FCM tests.

It works fine on android. The provisioning profile is added on XCode as well as the required capabilities.

I am using these versions:

"@react-native-firebase/app": "^20.1.0",
"@react-native-firebase/messaging": "^20.5.0",
async function requestUserPermission() {
  if (Platform.OS === 'android') {
    PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS);
  }
  const authStatus = await messaging().requestPermission();
  const enabled =
    authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
    authStatus === messaging.AuthorizationStatus.PROVISIONAL;

  if (enabled) {
    if (Platform.OS === 'ios') {

      const apnsToken = await messaging().getAPNSToken();
      console.log(apnsToken, '------');
      if (apnsToken) {
        await messaging().setAPNSToken(apnsToken);
        console.log('APNs Token:', apnsToken);
      } else {
        console.log('Failed to get APNs token');
      }
    }

    const fcmToken = await messaging().getToken();
    console.log(fcmToken, '-----');
    //toaster.custom(fcmToken, fcmToken);
    if (fcmToken) {
      setFcmToken(fcmToken);
      console.log('FCM Token:', fcmToken);
    } else {
      console.error('Failed to get FCM token');
    }
  }
}

useEffect(() => {
  requestUserPermission();
}, []);

useEffect(() => {
  notifee.onBackgroundEvent(async ({ type, detail }) => {
    console.log('background', type, detail);
    switch (type) {
      case EventType.PRESS:
        console.log(
          'send in data such as feed or other name and based on that redirect to post or screen',
        );
        break;
    }
  });
  
  notifee.onForegroundEvent(async ({ type, detail }) => {
    console.log('foreground', type, detail);
    switch (type) {
      case EventType.PRESS:
        console.log(
          'send in data such as feed or other name and based on that redirect to post or screen',
        );
        break;
    }
  });
}, []);

useEffect(() => {
  messaging().onNotificationOpenedApp(async remoteMessage => {
    
    console.log('on notification opened app', remoteMessage);
    onMessageReceived(remoteMessage);
  });

  messaging().setBackgroundMessageHandler(async remoteMessage => {
    
    console.log('Message handled in the background!', remoteMessage);
    onMessageReceived(remoteMessage);
  });
  
  const unsubscribe = messaging().onMessage(async remoteMessage => {
   
    console.log('on message', remoteMessage);
    onMessageReceived(remoteMessage);
  });

  return unsubscribe;
}, []);

const onMessageReceived = (message: FirebaseMessagingTypes.RemoteMessage | undefined) => {
  Platform.OS === 'android' &&
    Toast.show({
      type: 'customNotification',
      props: { text1: `${message?.notification?.body}` },
      position: 'top',
      swipeable: true,
      autoHide: false,
      onPress: () => {
        Toast.hide();

        console.log('on press, redirect to page');
      },
    });

  const notifeeData = {
    body: message?.notification?.body,
    data: message?.data,
    android: {
      channelId: 'default',
      actions: [
        {
          title: 'Mark as Read',
          pressAction: { id: 'read' },
        },
      ],
      // smallIcon: 'ic_large_icon',
      color: '#FFDE18',
      badgeIconType: AndroidBadgeIconType.LARGE,
      importance: AndroidImportance.HIGH,
      pressAction: {
        id: 'read',
      },
    },
    ios: {
      foregroundPresentationOptions: {
        badge: true,
        sound: true,
        banner: true,
        list: true,
      },
      actions: [
        {
          id: 'mark-as-read',
          title: 'Mark as Read',
        },
      ],
    },
  };
  notifee.displayNotification(notifeeData);
};

Next.js + Supabase + Google OAuth: User session not detected in middleware after authentication, causing redirect loop

I’m working on a Next.js project with Supabase authentication, and I’m encountering an issue where the user session is not being detected in the middleware after a successful authentication callback. This causes the middleware to continuously redirect to the signin page, creating a redirect loop.

Here’s the relevant code:

/api/auth/callback/route.ts :

import { NextResponse, NextRequest } from "next/server";
import { createClient } from "@/utils/supabase/server";
import config from "@/config";

export const dynamic = "force-dynamic";

// This route is called after a successful login. It exchanges the code for a session and redirects to the callback URL (see config.js).
export async function GET(req: NextRequest) {
  const requestUrl = new URL(req.url);
  const code = requestUrl.searchParams.get("code");
  const next = requestUrl.searchParams.get("next");
  console.log("next in auth callback:", next);
  if (code) {
    const supabase = createClient();
    const result = await supabase.auth.exchangeCodeForSession(code);
    
    console.log("exchangeCodeForSession result:", JSON.stringify(result, null, 2));

    if (result.error) {
      console.error("Error exchanging code for session:", result.error);
      return NextResponse.redirect(requestUrl.origin + '/auth-error');
    }

    // You can access other properties like result.data here if needed
  }

  // URL to redirect to after sign in process completes
  return NextResponse.redirect(requestUrl.origin);
}
 

middelware.ts:

/* middleware.ts */

import { type NextRequest } from 'next/server';
import { updateSession } from '@/utils/supabase/middleware';

export async function middleware(request: NextRequest) {
  return await updateSession(request);
}

export const config = {
  matcher: [
    /*
     * Match all request paths except:
     * - _next/static (static files)
     * - _next/image (image optimization files)
     * - favicon.ico (favicon file)
     * - images - .svg, .png, .jpg, .jpeg, .gif, .webp
     * Feel free to modify this pattern to include more paths.
     */
    '/((?!_next/static|_next/image|favicon.ico|.*\.(?:svg|png|jpg|jpeg|gif|webp)$).*)'
  ]
};


/* utils/supabase/middleware.ts */

import { createServerClient } from "@supabase/ssr";
import { NextResponse, type NextRequest } from "next/server";

export async function updateSession(request: NextRequest) {
  let supabaseResponse = NextResponse.next({
    request,
  });

  const supabase = createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() {
          return request.cookies.getAll();
        },
        setAll(cookiesToSet) {
          cookiesToSet.forEach(({ name, value, options }) =>
            request.cookies.set(name, value)
          );
          supabaseResponse = NextResponse.next({
            request,
          });
          cookiesToSet.forEach(({ name, value, options }) =>
            supabaseResponse.cookies.set(name, value, options)
          );
        },
      },
    }
  );

  // IMPORTANT: Avoid writing any logic between createServerClient and
  // supabase.auth.getUser(). A simple mistake could make it very hard to debug
  // issues with users being randomly logged out.

  const {
    data: { user },
  } = await supabase.auth.getUser();
  //console data
  console.log("user in middleware:",user)
  console.log("origin url in middleware:", request.nextUrl.basePath);
  if (
    !user &&
    !request.nextUrl.pathname.startsWith("/signin") &&
    !request.nextUrl.pathname.startsWith("/api")
  ) {
    // no user, potentially respond by redirecting the user to the login page
    const url = request.nextUrl.clone();
    
    url.pathname = "/signin";
    return NextResponse.redirect(url);
  }

  // IMPORTANT: You *must* return the supabaseResponse object as it is. If you're
  // creating a new response object with NextResponse.next() make sure to:
  // 1. Pass the request in it, like so:
  //    const myNewResponse = NextResponse.next({ request })
  // 2. Copy over the cookies, like so:
  //    myNewResponse.cookies.setAll(supabaseResponse.cookies.getAll())
  // 3. Change the myNewResponse object to fit your needs, but avoid changing
  //    the cookies!
  // 4. Finally:
  //    return myNewResponse
  // If this is not done, you may be causing the browser and server to go out
  // of sync and terminate the user's session prematurely!

  return supabaseResponse;
}

The issue:

  1. The /api/auth/callback route successfully calls exchangeCodeForSession.
  2. However, in the subsequent middleware, getUser() returns null.
  3. Because the user is null, the middleware redirects to the signin page.
  4. This creates a redirect loop, as the user is never detected as authenticated.

Logs:

GET /api/auth/callback?code=97738d2a-3b9f-4c2e-a1aa-d9c667478e29 307 in 29ms
user in middleware: null
user in middleware: null

What I’ve tried:
Logging the result of exchangeCodeForSession in the callback route, which shows a successful session creation.

Checking the middleware multiple times, but it consistently shows the user as null.

Questions:

Why isn’t the user session being detected in the middleware after a successful callback?

Is there a timing issue where the middleware is executing before the session is fully established?

How can I ensure that the session is properly set and detectable in the middleware after the callback?

What’s the best way to prevent the redirect loop while still protecting routes that require authentication?

Environment:

"@supabase/ssr": "^0.4.0",
"@supabase/supabase-js": "^2.38.3",
 "next": "^14.0.0",

Any insights or suggestions would be greatly appreciated. Thank you!

How can I reset clientHeight after exiting to an external browser?

Exiting to an external browser is shrinking clientHeight and causing height inconsistencies. How can I reset it? The value is read-only, and I tried to set the body, but it didn’t fix the issue. I also don’t want to reload the page. I started working on this hook that should reset the client height, but it isn’t working.

const useBodyMinHeight = (location: 'home' | 'loading' | 'application') => {
  const viewportHeight = `${window.innerHeight}px`;
  const setBodyMinHeight = (location: 'home' | 'loading' | 'application') => {
    // document.body.style.backgroundColor = '#E4D00A'; // <--- Debugging color

    // Forces reflow
    void document.body.offsetHeight;
    void document.body.clientHeight;
    void document.body.scrollHeight;
    void document.body.offsetHeight;

    // Warning clientHeight is causing the body to be too small
    const targetContainer = document.getElementById(location);
    if (targetContainer) {
      document.body.style.height = viewportHeight;
      targetContainer.style.height = viewportHeight;
      targetContainer.style.minHeight = viewportHeight;
    }
  };

  if (isStandaloneMode()) {
    setBodyMinHeight(location);
  }

  useLayoutEffect(() => {
    if (isStandaloneMode()) {
      setBodyMinHeight(location);
      window.addEventListener('focus', () => setBodyMinHeight(location));
      window.addEventListener('resize', () => setBodyMinHeight(location));

      const { orientation } = window.screen;

      if (orientation) {
        orientation.addEventListener('change', () => setBodyMinHeight(location));
      }
    }
  }, [location]);
};

export default useBodyMinHeight;

How can I use a DateRangePicker as a SingleDatePicker without force the option and lose the DateRange functionality?

I am using this DateRangePicker jQuery plugin and it works perfect for when you are using it with dates ranges but I want to be able also to select just one date without lose the range functionality. In other words: if you open both calendars and pick just a date from each then I want to be able to click the Apply button. My issue: the click event for the calendars is not exposed and therefore I am unable to catch when the user click and where.

I know the plugin offer a setting singleDatePicker that when it is set to true it shows only one calendar but this is not what I am looking for. If I force this then the second calendar isn’t show up.

See my code below (Fiddle here):

$(document).ready(function () {
    const dateRangePicker = $('.dateRangePicker');
    dateRangePicker.daterangepicker({
        autoUpdateInput: false,
        linkedCalendars: false,
        opens: 'left',
        locale: {
            cancelLabel: 'Clear'
        },
        timePicker: false,
        format: 'm/d/Y'
    });

    dateRangePicker.on('apply.daterangepicker', function (ev, picker) {
        const startDate = picker.startDate.format('MM/DD/YYYY');
        const endDate = picker.endDate.format('MM/DD/YYYY');

        if (startDate === endDate) {
            $(this).val(startDate);
        } else {
            $(this).val(startDate + ' ... ' + endDate);
        }
    });

    dateRangePicker.on('showCalendar.daterangepicker', function (ev, picker) {
        $('.applyBtn').prop('disabled', true);
    });

    dateRangePicker.on('cancel.daterangepicker', function (ev, picker) {
        $(this).val('');
    });
});

as soon as you click a date on any calendar then the plugin is forcing me to pick a second date which I would or wouldn’t because in my form I can force always a range, I need to add the ability to choose a date or a range of dates.

Can I get some ideas for how to trick the plugin to achieve what I am looking for?

Parametrizing regex in require.context()

In my react component, I was trying to retrieve a file based on a param passed into that e.g.

const Section = () => {
    const params = useParams();
    const sectionId = params.sectionId;
    const regex = new RegExp(`Section${sectionId}.json$`);

    const section =  require.context('../json', false, regex);

It fails though with __webpack_require__(...).context is not a function error because according to the webpack doc: The arguments passed to require.context must be literals!

So I ended up retrieving all files using a literal and then getting the one I need based on the param e.g.

const sections = require.context('../json', false, /Section[1-9].json$/);
const sectionKey = Object.keys(sections).filter(key => regex.test(key));
const section = sections[sectionKey];

I find such a solution rather inconvenient and potentially not scaling too well in case of large number of files.

What would be a correct approach to this issue?

JavaScript generating always the same numbers on the second for loop

The script:

let col1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] 
let col2 = [16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
for(let i = 0; i < 5; i++) {
    const random = Math.floor(Math.random() * col1.length + 1)
    const index = col1.indexOf(random)
    const number = col1.at(index)
    col1.splice(index, 1)
    console.log(number)
}
for(let i = 0; i < 5; i++) {
    const random = Math.floor(Math.random() * col2.length + 1)
    const index = col2.indexOf(random)
    const number = col2.at(index)
    col2.splice(index, 1)
    console.log(number)
}

The first for loop always generates 5 random numbers from the first array. But the second for loop always shows the same results (30, 29, 28, 27, 26). What’s causing this behavior?

Why does a looping animation in useChain refuse to loop?

I want to have a looping animation triggered by a previous animation. To trigger an animation after one ends, we can use usechain.

However, if I want one of the animations to loop, it just… doesn’t work.

Here’s the sample animation code:

  const blueSpringRef = useSpringRef();
  const pinkSpringRef = useSpringRef();

  const [blueSpring, blueSpringAPI] = useSpring(
    () => ({
      ref: blueSpringRef,
      from: { x: 0 },
      to: { x: 100 },
      config: { duration: 3000 },
    }),
    []
  );

  const [pinkSpring, pinkSpringAPI] = useSprings(
    2,
    (i) => ({
      ref: pinkSpringRef,
      from: { y: 100 },
      to: { y: 200 },
      loop: true,
      delay: 1000 * i,
    }),
    []
  );


  useChain([blueSpringRef, pinkSpringRef], [0, 0.5], 3000);

Making the duration of useChain does not help.

Here’s a codesandbox:
https://codesandbox.io/p/sandbox/happy-fire-dpv9yf

Making a post request using AJAX in Javascript to a Python Flask Server Backend and receiving a 415 error

I am fairly new to web development so I apologize if my terminology is off, but some friends and I are working on a personal project website and I have not been able to find a lot of information relevant to our exact tech stack/issues so I am braving the stack overflow forms. If anyone reads through this and knows where to find relevant documentation I should read (even if you aren’t sure of an exact answer to my problem) sharing it would be greatly appreciated. We have a limited budget of 0 dollars and as a result are hosting our Flask backend on a pythonanywhere site and we are hosting our frontend on a GitHub Jekyll site. Originally we were going to make requests from our front end to our back end using JavaScript’s fetch function and pass the parameters our backend needed through our URL but we quickly realized we needed to pass a lot of parameters and this would be clunky. So after some research we found out we could add the AJAX library to our project and make a POST request sending a JSON along with our request which the back end could then parse for all our parameters and send us back the needed information. However, I have been unable to successfully make a POST request after about a week of on and off scouring the internet for similar examples.

The first issue we were running into was a CORS issue which seemed to be due to our front end and our back end being hosted at different spots. (Note that I am using local host here for testing purposes but the same issues still arise.)

This was solved by configuring our python code like so:

from flask import Flask, after_this_request, jsonify, request

app = Flask(__name__)

@app.route("/testRoute", methods=['POST', 'GET'])
def testRoute():

    #boilerplate code, dont touch this
    @after_this_request
    def add_header(response):
         response.headers.add('Access-Control-Allow-Origin', '*')
         return response

    if request.method == 'POST':
        print("test")
        elems = request.json
        print(elems)
        return jsonify({})

    return jsonify({'goodbye':'world'})

And our JavaScript code like so:

function sendData() {
    $.ajax({
        type : 'POST',
        url : 'http://127.0.0.1:5000/testRoute',
        data : {'hello':'world'},
        success: function(response) {
            console.log(response);
        },
        error: function(error) {
            console.log(error);
        }
    })
}

Which led to a 415 error when calling the JavaScript code.

One Stack Overflow post suggested adding a header to our Javascript request like so:

function sendData() {
    $.ajax({
        type : 'POST',
        headers : {
            'Content-type':'application/json', 
            'Accept':'application/json'
        },
        url : 'http://127.0.0.1:5000/testRoute',
        data : {'hello':'world'},
        success: function(response) {
            console.log(response);
        },
        error: function(error) {
            console.log(error);
        }
    })
}

However making the request with these headers added gives a response of “Access to XMLHttpRequest at ‘http://127.0.0.1:5000/testRoute’ from origin ‘null’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.” Which I assume is the CORS error from before.

Another post suggested changing the Python file to:

from flask import Flask, after_this_request, jsonify, request

app = Flask(__name__)

@app.after_request
def after_request(response):
    header = response.headers
    header['Access-Control-Allow-Origin'] = '*'
    header['Access-Control-Allow-Headers'] = 'Content-Type, Authorization, Accept'
    header['Access-Control-Allow-Methods'] = 'OPTIONS, HEAD, GET, POST, DELETE, PUT'
    return response

@app.route("/testRoute", methods=['POST', 'GET'])
def testRoute():

    if request.method == 'POST':
        print("test")
        elems = request.json
        print(elems)
        return jsonify({})

    return jsonify({'goodbye':'world'})

As well as removing the headers from our JavaScript function. However, this still just gave us the 415 error.

I have also tried formatting the headers with some additional information as a third post suggested:

function sendData() {
    let headers = new Headers();

    headers.append('Content-Type', 'application/json');
    headers.append('Accept', 'application/json');
    headers.append('Access-Control-Allow-Origin', 'http://127.0.0.1:5000/testRoute');
    headers.append('Access-Control-Allow-Credentials', 'true');

    $.ajax({
        type: 'POST',
        headers: headers,
        data : {'hello':'world'},
        success: function (e) {
            console.log(e);
        },
        error: function(error) {
            console.log(error);
        }
   }); 
}

But this still led to the above CORS issues.

A fourth post also suggested changing the the elems = request-get_json line like so:

elems = request.get_json(force=True) 

And I tested with various different header settings in both the JavaScript and Python files but to no avail.

I am starting to feel like I am going in circles, this seems like it should be an easy issue to fix but I think I just lack the knowledge about this subject to understand which headers to change and why. Seemingly if the Flask Server sends a response header then the JavaScript isn’t allowed to include any headers with its request, but if the Flask Server doesn’t have the headers then we run into the CORS issues.

get duration of raw audio file with javascript

I have a raw audio file like this:

const rawAudio = data:audio/webm;codecs=opus;base64,GkXfo59ChoEBQveBAULygQRC84EIQoKEd2VibUKHgQRChYECGFOAZwH/////////FUmpZpkq17GDD0JATYCGQ2hyb21lV0GGQ2hyb21lFlSua7+uvdeBAXPFh+Wa3g0oH66DgQKGhkFfT1BVU2Oik09wdXNIZWFkAQEAAIC7AAA

And I want to get the duration of this audio file.

Here is what I tried:

const onDrop = (file) => {
  const audio = document.createElement("audio")
  audio.setAttribute("src", URL.createObjectURL(file))
  audio.setAttribute("crossorigin", "anonymous")

  console.log(audio) // 

  audio.addEventListener("loadedmetadata", () => {
    console.log("loadedmetadata")
    const duration = audio.duration
    console.log(duration)
  })
}

var binaryData = []
binaryData.push(Card.audios.explain[0])

onDrop(new Blob(binaryData))

But loadedmetadata never fires !!

How would you do that?

How does Webpack handle images in src folder for React application?

Am following a React tutorial which has some images in the src/assets folder and imports them by giving a relative path to component files. I’m a bit confused how this is handled for production.

I understand that generally webpack bundles all the js and css together to create a single bundle file but if you have large image file assets in your src folder, then how are they handled for production? Do you need to upload them into the same /assets folder structure when you deploy your app to a web server as the code will still be looking for those relative path references to display the images?

Change a Boolean value in parent from child component in Vue

I’m trying to update a Boolean variable setup in the parent, from a child component.

I’ve passed the variable as a prop in the parent to the child component:

<script>
  let isFinished = false;
</script>

<template>
  <Child
    v-if="isFinished === false"
    :isFinished = isFinished
  />

  <Child2
    v-if="isFinished === true"
    :isFinished = isFinished
  />
 </template>

and I can see it being received with a console.log in the child component, but I get an error when I try to change the value saying it’s read only:

export default {
    props: {
        isFinished: Boolean
    }, 
    methods: {
        submit: function(e) {
            console.log('prop recieved:', this.isFinished);
            this.isFinished = true;
        }
    }
}

What else do I need to do to be able to change the Boolean in the child so it’s passed back up to the parent to switch the components to render?

Any help would be appreciated thank you.

React NextJS Redux Took Kit Polling not getting data when interval time is met

Have been working with the React Redux Tool-kit and trying to get polling to work with an api call that I have. I’ve pretty much copied the one from the Documentation they have and put it in my project. The Pokemon test one in my project works just fine. How ever when I add my api, or one like the dog api listed below. I receive and display the JSON information but when the interval time is met (3, 10 seconds) nothing is updated or fetched, the component background isn’t changed and the information isn’t updated.

I added the manual refresh button and that works just fine.

I look at the network tab and all I see is the one request and nothing after.

Here is the link the docs working example.
RTK polling Pokemon Demo

If I am missing any code please let me know, Ill be sure to post it.

apiSlice.ts

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'

export const dogsApi = createApi({ 
   reducerPath: 'dogsApi', 
   baseQuery: fetchBaseQuery({ baseUrl: 'https://dog.ceo/api/breeds/image/'}), 
   endpoints: (builder) => ({ 
    getDogs: builder.query({
        query: () => 'random', 
    })         
   })
})

export const { useGetDogsQuery } = dogsApi

store.ts

export const store = configureStore({ 
reducer: {          
    [dogApi.reducerPath]: dogApi.reducer, 

}, 
middleware: getDefaultMiddleware => getDefaultMiddleware()
            .concat(dogApi.middleware)
})

layout.tsx

        <Provider store={store}>
            {children}
        </Provider>

TestComponent.tsx

  const [pollingInterval, setPollingInterval] = React.useState(3000)

  const { data: doggie, error, isLoading, isFetching, refetch } =
      useGetDogsQuery( {pollingInterval})
  return (
    <div
      style={{
        float: 'left',
        textAlign: 'center',
        ...(isFetching ? { background: '#e6ffe8' } : {}),
  }}
>
    {error ? (
      <>Oh no, there was an error loading Notices</>
    ) : isLoading ? (
      <>Loading...</>
    ) : doggie? (  
    
    <>        
    <h3>Notice Name</h3>
    <div>
      <p>There is and image here</p>
      <div style={{ minWidth: 96, minHeight: 96 }}>
         <img
          src={doggie.message}
          alt={'doggie'}
          style={{ ...(isFetching ? { opacity: 0.3 } : {}) }}
        /> 

      </div>
    </div>
    <div>
      <p>label here</p>
      <p>Select here for intervals</p>
    </div>
    <div>
        <p>There is a button here</p> 
        <label style={{ display: 'block' }}>Polling interval {pollingInterval}</label>
        
        <button onClick={refetch} disabled={isFetching}>{isFetching ? 'Loading' : 'Manually refetch'}</button>
        <div>{JSON.stringify(doggie)}</div>
        
          <>            
        </>        
    </div>
    </>  
    ): (
      'No Data'
    )}
  </div>          
  )

Get all items of a HTML element

Below is the output of alert( rd.innerHTML );:

 <ruby><rb>「わたし</rb><rt><br>watashi</rt></ruby><ruby><rb>は</rb><rt><br>wa</rt></ruby>」&lt;Name des Sprechers&gt;<br><ruby><rb>です</rb><rt><br>desu</rt></ruby>。

I like to iterate over all those elements. I tried (among others):

var items = rd.getElementsByTagName("*");
for (var i = 0; i < items.length; i++) {
    var item = items[i];
    alert( item.innerHTML);
}

But for the loop above I will get

  • <rb>「わたし</rb><rt><br>watashi</rt>
  • 「わたし
  • n watashi
  • <rb>は</rb><rt><br>wa</rt>
  • n wa
  • <rb>です</rb><rt><br>desu</rt>
  • です
  • n desu

How can I loop this HTML and also get the item 」&lt;Name des Sprechers&gt;<br>