Redux: Actions must be plain objects error – How to resolve?

I’m encountering an error in my React Native application when trying to save user data and login details to Firebase using Redux. The error message I’m receiving is:

[Error: Actions must be plain objects. Instead, the actual type was: ‘undefined’. You may need to add middleware to your store setup to handle dispatching other values, such as ‘redux-thunk’ to handle dispatching functions.

I’m using Redux to manage my application’s state, and I’ve configured a store using @reduxjs/toolkit. The strange thing is that the data is being saved successfully to Firebase, but I’m still getting this error.

Here’s a simplified version of my Redux setup:

Signup.js

const isTestMode = true;
const initialState = {
  inputValues: {
    username: isTestMode ? "John Doe" : "",
    email: isTestMode ? "[email protected]" : "",
    password: isTestMode ? "12121212" : "",
  },
  inputValidities: {
    username: false,
    email: false,
    password: false,
  },
  formIsValid: false,
};

export default function Signup({ navigation }) {
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(null);
  const [formState, dispatchFormState] = useReducer(reducer, initialState);
  const dispatch = useDispatch();

  const inputChangedHandler = useCallback(
    (inputId, inputValue) => {
      const result = validateInput(inputId, inputValue);
      dispatchFormState({ inputId, validationResult: result, inputValue });
    },
    [dispatchFormState]
  );

  const signupHandler = async () => {
    try {
      setIsLoading(true);
      const action = signUp(
        formState.inputValues.username,
        formState.inputValues.email,
        formState.inputValues.password
      );
      await dispatch(action);
      Alert.alert("Account Successfully created", "Account created");
      setError(null);
      setIsLoading(false);
      navigation.navigate("Login");
    } catch (error) {
      console.log(error);
      setIsLoading(false);
      setError(error.message);
    }
  };

 
  return (
    <SafeAreaProvider>
      <View style={styles.container}>
        <View style={styles.inputView}>
          <Inputs
            id="username"
            placeholder="Username"
            errorText={formState.inputValidities["username"]}
            onInputChanged={inputChangedHandler}
          />
          <Inputs
            id="email"
            placeholder="Enter your email"
            errorText={formState.inputValidities["email"]}
            onInputChanged={inputChangedHandler}
          />
          <InputsPassword
            id="password"
            placeholder="Password"
            errorText={formState.inputValidities["password"]}
            onInputChanged={inputChangedHandler}
          />
        </View>

        <Buttons
          title="SIGN UP"
          onPress={signupHandler}
          isLoading={isLoading}
        />

        <StatusBar style="auto" />
      </View>
    </SafeAreaProvider>
  );
}

AuthSlice.js

import { createSlice } from "@reduxjs/toolkit";

const authSlice = createSlice({
  name: "auth",
  initialState: {
    token: null,
    userData: null,
    didTryAutoLogin: false,
  },
  reducers: {
    authenticate: (state, action) => {
      const { payload } = action;
      state.token = payload.token;
      state.userData = payload.userData;
      state.didTryAutoLogin = true;
    },
    setDidTryAutoLogin: (state, action) => {
      state.didTryAutoLogin = true;
    },
  },
});

export const authenticate = authSlice.actions.authenticate;
export default authSlice.reducer;

Store.js

import { configureStore } from "@reduxjs/toolkit";
import authSlice from "./authSlice";

export const store = configureStore({
  reducer: {
    auth: authSlice,
  },
});

I don’t understand getting at least a pack(javascript) [closed]

    const a = function (b) {
      let max = b[0];
      let min = b[0];
      for (let i = 0; i < b.length; i++) {
        const c = b[i];
        if (c > max) {
          max = c;
          console.log(max, c);
        }
        if (c < min) { <============================
          min = c;
          console.log(min, c);
        }
      }
         
    };

I understand that the maximum value is obtained, but I don’t understand that the minimum value is obtained

Monaco editor remove tab

Прошу помочь уже несколько дней не понимаю в чем дело.

Я написал онлайн редактор кода на основе monaco editor.Начал делать функции вкладок и теперь моем коде либо не правильно работает удаления одного монако эдитора или что то не так делаю. В общем вкладки у меня построены так

[все линии
 [ линия
   [ таб
     {} и обьекты которые хранят модель для эдитора и еще данные
   ],
 ],
]

проблема в том что когда я удаляю tab который не является последним должен по идеи просто удалиться.

[
 [ 
   [ 
     {} 
   ],
   [ удаляю вот этот например
     {} 
   ],
   [ 
     {} 
   ],
 ],
]

то консоль выдает ошибку model disposed хотя я же просто должен был удалить массив.

Body от него все идет

import { useSelector } from "react-redux";
import Tab from "./Tab";
import { useEffect, useState } from "react";
import {tabs} from './getItems'

const Body = () => {

    const themeValue = useSelector(state => state.options.theme);
    const plan = useSelector(state => state.editorAll.tabs)
    const check = useSelector(state => state.editorAll.check)

    useEffect(() => {
        if(plan[0][0].length > 0){
            localStorage.setItem('tabs', JSON.stringify(plan.map(tab => tab.map(innerArray => innerArray.map(obj => ({ ...obj, model: null }))))));
        }
    },[plan])

    return (
        <div className={`body ${themeValue}`}>
            {
                plan.map((line,i) => (
                    <div className="body_line" key={i}>
                        {
                            line.map((e,tabI) => (
                                <Tab key={tabI} plan={tabs} index={{line:i,tab:tabI}}/>
                            ))
                        }
                    </div>
                ))
            }
            <div className={"body_check "+check}>
                <div className="body_check_right"></div>
                <div className="body_check_bottom"></div>
            </div>
        </div>
    );
};

export default Body;

import { useEffect, useRef, useState} from 'react';
import Editor from '@monaco-editor/react';
import jsonpath from 'jsonpath';
import { useDispatch, useSelector } from 'react-redux';
import { addRefAction } from '../../store/reducers/ref';
import { changeAllBoolean } from '../../store/reducers/boolean/allBoolean';
import { changeCursorInfo } from '../../store/reducers/components/editorCursorLine';
import { changeEditorAll } from '../../store/reducers/components/editorAll';
import Inset from './Inset';


export default function Tab({plan,index}) {

    const editRef = useRef(null);
    const monacoRef = useRef(null);
    const dispatch = useDispatch();
    const themeValue = useSelector(state => state.options.theme);
    const autoSaveValue = useSelector(state => state.options.saveBoolean);
    const minimapValue = useSelector(state => state.options.minimap);
    const indentationValue = useSelector(state => state.options.indentation);
    const wrapTextValue = useSelector(state => state.options.wrapText);
    const showIndentationValue = useSelector(state => state.options.showIndent)
    const fontSizeValue = useSelector(state => state.options.fontSize);
    const tabSizeValue = useSelector(state => state.options.tabSize);
    const insertSpaceValue = useSelector(state => state.options.insertSpace);
    const tabs = useSelector(state => state.editorAll.tabs[index.line][index.tab])
    const allTabs = useSelector(state => state.editorAll.tabs)
    const ownId = index
    const id = useSelector(state => state.editorAll.activeInset)
    const languageValue = useSelector(state => state.editorAll.tabs[id.line][id.tab][id.inset]?.lang)
    const ref = useSelector(state => state.ref.ref)

    const [actualIndex, setactualIndex] = useState(0)
    const [actualObj, setactualObj] = useState({name: 'untilted', lang: 'json', model: null, code:'',cursor:{column:0,lineNumber:0}})
    const [insetObj, setinsetObj] = useState(null)

    function handleEditorDidMount(editor, monaco) {
        editRef.current = editor;
        monacoRef.current = monaco;
        }
        editor.onDidChangeModelContent(() => {
            if(editor.getModel()){
                dispatch(changeAllBoolean('CAN_UNDO',editor.getModel().canUndo()))
                dispatch(changeAllBoolean('CAN_REDO',editor.getModel().canRedo()))
            }
        });
        editor.onDidChangeModel(() => {
            if(editor.getModel()){
                dispatch(changeAllBoolean('CAN_UNDO',editor.getModel().canUndo()))
                dispatch(changeAllBoolean('CAN_REDO',editor.getModel().canRedo()))
            }
        });
        if (monaco && tabs.length === 0) {
            if(plan && autoSaveValue){
                createSaveInsets(plan[index.line][index.tab])
            } else{
                dispatch(changeEditorAll('ADD_OBJECT',{newId:ownId,newObj:{...actualObj,model:editor.getModel()}}))
            }
        }
        if(tabs.length>0){
            const newModel = monacoRef.current.editor.createModel(tabs[0].code, tabs[0].lang)
            dispatch(changeEditorAll('REPLACE',{id:{...index,inset:0},obj:{...tabs[0],model: newModel}}))
            setinsetObj({...tabs[0],model: newModel});
        }
    }
    const changeEditor = () => {
        if (editRef.current) {
            if (editRef.current.getValue().trim() === '') {
                dispatch(changeEditorAll('EMPTY',false));
            } else{
                dispatch(changeEditorAll('EMPTY',true));
            }
        }
    };
    const createInset = () => { 
        let newName = 'untilted'
        const untitledObject = tabs.find(obj => obj.name === 'untilted');
        if(untitledObject){
            let numbers = tabs
            .filter(obj => obj.name.startsWith('untilted'))
            .map(obj => {
                const match = obj.name.match(/untilted ((d+))/);
                return match?parseInt(match[1]):0;
            });
            let number = 1;
            while (numbers.includes(number)) {
                number++;
            }
            newName = `untilted (${number})`;
        }
        const newModel = monacoRef.current.editor.createModel('', 'json')
        dispatch(changeEditorAll('ADD_OBJECT',{newId:ownId,newObj:{ name: newName, lang: 'json', model: newModel, code:'',cursor:{column:0,lineNumber:0}}}))
    }
    const deleteInset = (name,boolean) => {
        const lineLength = allTabs[index.line].length
        if (tabs.length == 1 && lineLength > 1){
            monacoRef.current.editor.getModels().forEach(e => {
                if (e.id === tabs[0]?.model?.id) {
                    e.dispose();
                }
            });
            dispatch(changeEditorAll('REMOVE_TAB',index))
            console.log(monacoRef.current.editor.getModels())
        } else if (tabs.length > 1 ) {
            const modelId = tabs.find(e => e.name === name)?.model?.id
            monacoRef.current.editor.getModels().forEach(e => {
                if(e.id == modelId) {
                    e.dispose()
                }
            })
            dispatch(changeEditorAll('REMOVE_OBJECT',{oldId:id,oldName:name}))
            if (boolean) {
                if(actualIndex!==0){
                    setactualIndex(actualIndex-1);
                }
            } else{
                setactualIndex(tabs.findIndex(e => e.name == name)>actualIndex?actualIndex:actualIndex-1);
            }
        }
    }
    const changeRef = () => {
        console.log(editRef.current.getModel().id)
        dispatch(addRefAction({ref:editRef,monaco:monacoRef}));
        dispatch(changeAllBoolean('ACTIVE_INSET_CHANGE', {line:index.line,tab:index.tab,inset:actualIndex}));
    }
    const createSaveInsets = (plan) => { 
        plan.forEach((e) => {
            const newModel = monacoRef.current.editor.createModel(e.code, e.lang)
            dispatch(changeEditorAll('ADD_OBJECT',{newId:ownId,newObj:{ name: e.name, lang: e.lang, model: newModel, code:e.code,cursor:e.cursor}}))
        })
    }

    useEffect(() => {       
        if(id.tab === index.tab && editRef.current){
            dispatch(addRefAction({ref:editRef,monaco:monacoRef}));
            console.log(monacoRef.current.editor.getModels())
        }
    });

    useEffect(() => {
        if (tabs.length > 0) {
            const names = tabs.map(e => e?.model?.id == insetObj?.model?.id)
            if(insetObj == null || !names[0]){
                // setinsetObj({...tabs[0]});
            }
        } 
    }, [tabs]);

    useEffect(() => {
        if(editRef.current){
            const name = editRef.current?.getModel()?.id
            if(insetObj && name !== insetObj?.model?.id){ 
                editRef.current.setModel(insetObj.model)
            }
        }
    }, [insetObj]);
    
    useEffect(() => {
        if (languageValue && editRef && id.tab == index.tab && id.line == index.line ) {
            const model = editRef.current.getModel();
            monacoRef.current.editor.setModelLanguage(model,languageValue)
        }
    }, [languageValue]);
    
    useEffect(() => {
        if(id.tab == index.tab && editRef.current){
            if(editRef.current.getModel()){
                dispatch(changeAllBoolean('CAN_UNDO',editRef.current.getModel().canUndo()))
                dispatch(changeAllBoolean('CAN_REDO',editRef.current.getModel().canRedo()))
            }
        }
    },[id])

    return (
        <div className='body_tab' onClick={changeRef}>
            <div className='body_tab_insets'>
                {
                    tabs.map((e,i) => (
                        <Inset inset={insetObj} setInset={setinsetObj} tabIndex={ownId} editRef={editRef.current} object={e} ownIndex={i} actual={actualIndex} setIndex={setactualIndex} deleting={deleteInset} key={i}/>
                    ))
                }
                <div className='body_tab_insets_add'>
                    <svg onClick={() => createInset()} xmlns="http://www.w3.org/2000/svg" height="22" viewBox="0 -960 960 960" width="22"><path d="M464-464H280v-32h184v-184h32v184h184v32H496v184h-32v-184Z"/></svg>
                </div>
            </div>
            <div className="body_tab_editor">
                <Editor
                    className="editor"
                    width={'100%'}
                    height={'100%'}
                    theme={themeValue === 'black' ? 'customTheme' : ''}
                    onMount={handleEditorDidMount}
                    onChange={changeEditor}
                    options={{
                        renderWhitespace: indentationValue ? 'all' : '',
                        automaticLayout: true,
                        minimap: { enabled: minimapValue },
                        guides: {
                            indentation: showIndentationValue, 
                        }
                    }}
                />
            </div>
        </div>
    )
}
import { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useDrag } from 'react-dnd';

import { changeAllBoolean } from "../../store/reducers/boolean/allBoolean";
import { changeEditorAll } from "../../store/reducers/components/editorAll";

export default function Inset({inset,setInset,tabIndex,editRef,object,ownIndex,actual,setIndex,deleting}) {  

    const [menuShow, setmenuShow] = useState(false)
    const tabs = useSelector(state => state.editorAll.tabs[tabIndex.line][tabIndex.tab])
    const id = useSelector(state => state.editorAll.activeInset)
    const check = useSelector(state => state.editorAll.check)
    const allTabs = useSelector(state => state.editorAll.tabs)

    const dispatch = useDispatch()

    const changeMenuShow = (event) => {
        event.preventDefault(); 
        if (!menuShow) { 
            setmenuShow(true)
        }
    }
    const setModel = () => {
        setIndex(ownIndex);
    }
    const remove = (e) => {
        e.stopPropagation(); 
        setmenuShow(false)
        const lineLength = allTabs[tabIndex.line].length
        if(tabs.length == 1 && lineLength > 1){
            let newTab = tabIndex.tab+1==lineLength?(lineLength-2):tabIndex.tab
            dispatch(changeAllBoolean('ACTIVE_INSET_CHANGE', {line:tabIndex.line,tab:newTab,inset:0}));
        }
        deleting(object.name,actual==ownIndex?true:false);
    }
    const removeAll = (e) => {
        e.stopPropagation(); 
        setmenuShow(false)
        dispatch(changeEditorAll('REMOVE_ALL_OBJECT',{RMid:tabIndex,RMobj:object}))
        setIndex(0);
        editRef.setModel(object.model)
        dispatch(changeAllBoolean('ACTIVE_INSET_CHANGE',{...tabIndex,inset:ownIndex}))
    }
    const removeRight = (e,side) => {
        if(ownIndex !== tabs.length) {
            e.stopPropagation();
            setmenuShow(false)
            dispatch(changeEditorAll('REMOVE_ALL_SIDES_OBJECT', { RSid: tabIndex, RSown: ownIndex, side: side }));
        }
        if(ownIndex<actual && side == 'right'){
            setIndex(ownIndex);
            editRef.setModel(object.model)
            dispatch(changeAllBoolean('ACTIVE_INSET_CHANGE',{...tabIndex,inset:ownIndex}))
        } 
        if(ownIndex>=actual && side == 'left'){
            setIndex(0);
            editRef.setModel(object.model)
            dispatch(changeAllBoolean('ACTIVE_INSET_CHANGE',{...tabIndex,inset:ownIndex}))
        } 
        if (ownIndex < actual && side === 'left') {
            setIndex(actual-ownIndex);
            editRef.setModel(object.model);
            dispatch(changeAllBoolean('ACTIVE_INSET_CHANGE', { ...tabIndex, inset: ownIndex }));
        }
    }

    const handleDragEnd = (item, monitor) => {
        const clientOffset = monitor.getClientOffset();
        const clickedElement = document.elementFromPoint(clientOffset.x, clientOffset.y);
        if(clickedElement.classList[0] == 'body_check_right'){
            if(tabs.length > 1){
                dispatch(changeEditorAll('ADD_TAB',{tabObj:object,tabId:tabIndex.line}))
                setmenuShow(false)
                deleting(object.name,actual==ownIndex?true:false);
            }
        } else if(clickedElement.classList[0] == 'body_check_bottom') {
            console.log(1)
        }
        dispatch(changeEditorAll('CHANGE_CHECK', false));
    };

    const [{ isDragging }, drag] = useDrag({
        type:'box',
        item: () => {
            dispatch(changeEditorAll('CHANGE_CHECK',true))
            return { type: 'box'.BOX, id }
        },
        collect: (monitor) => ({
            isDragging: monitor.isDragging(),
        }),
        end:handleDragEnd,
    });

    useEffect(() => {
        if (menuShow) {
            const handleOutsideClick = (event) => {
                const div = document.querySelector('.body_tab_insets_inset_menu')
                const array = event.composedPath().includes(div)
                if (!array) {
                    setmenuShow(false);
                    document.removeEventListener("click", handleOutsideClick)
                }
            };
            // const handleContextMenu = (event) => {
            //     if (event.button === 2 && menuShow) {
            //         const div = document.querySelector('.body_tab_insets_inset_menu')
            //         const array = event.composedPath().includes(div)
            //         if (!array) {
            //             setmenuShow(false);
            //             document.removeEventListener("contextmenu", handleContextMenu)
            //         }
            //     }
            // };
            document.addEventListener("click", handleOutsideClick);
            // document.addEventListener("contextmenu", handleContextMenu);
        }
    }, [menuShow]);

    useEffect(() => {
        if(editRef){
            const modelChangeListener = editRef.onDidChangeModelContent(() => {
                const newCursorPos = editRef.getPosition();
                if(actual === ownIndex && id.tab == tabIndex.tab){
                    dispatch(changeEditorAll('REPLACE',{id:{...id,inset:actual},obj:{...tabs[id.inset],cursor:newCursorPos,code:editRef.getValue()}}))
                }
            });
            return () => {
                modelChangeListener.dispose(); 
            };
        }
    }, [editRef, actual, ownIndex, id, tabs]);
    
    useEffect(() => {
        if (actual === ownIndex && id.tab == tabIndex.tab && inset?.model?.id !== object.model.id) {
            setInset(object)
            editRef.focus()
            editRef.setPosition(tabs[actual].cursor);
            dispatch(changeAllBoolean('ACTIVE_INSET_CHANGE', {line:tabIndex.line,tab:tabIndex.tab, inset: ownIndex}));
        }
    }, [actual]);

    return (
        <div 
            ref={drag} 
            style={{opacity: isDragging ? 0.5 : 1}}
            className={`body_tab_insets_inset ${actual==ownIndex?'active':''}`} 
            onClick={() => setModel()} 
            onContextMenu={(e) => changeMenuShow(e)}
        >
            <div className='body_tab_insets_inset_line'></div>
            <h5>{object.lang ? object.lang.toUpperCase() : ''}</h5>
            <h4>{object.name}</h4>
            <svg onClick={(event) => remove(event)} xmlns="http://www.w3.org/2000/svg" height="18" viewBox="0 -960 960 960" width="18"><path d="M291-267.692 267.692-291l189-189-189-189L291-692.308l189 189 189-189L692.308-669l-189 189 189 189L669-267.692l-189-189-189 189Z"/></svg>
            <div className={"body_tab_insets_inset_menu "+menuShow}>
                <h3 onClick={(event) => remove(event)}>Close Tab</h3>
                <h3 onClick={(event) => removeAll(event)}>Close Other Tab</h3>
                <h3 onClick={(event) => removeRight(event,'right')}>Close Tabs to the Right</h3>
                <h3 onClick={(event) => removeRight(event,'left')}>Close Tabs to the Left</h3>
                <div className="body_tab_insets_inset_menu_line"></div>
                <h3>Split Up</h3>
                <h3>Split Down</h3>
                <h3>Split Left</h3>
                <h3>Split Right</h3>
            </div>
        </div>
    )
}

также так выглядит мой redux

state

activeInset:{line:0,tab:0,inset:0},
tabs:[
        [
            [
                
            ],
        ],
],

actions

case 'REMOVE_TAB':
            return {
                ...state,
                tabs: state.tabs.map((tabLine, lineIndex) => {
                    if (lineIndex === action.payload.line) {
                        return tabLine.filter((_, tabIndex) => tabIndex !== action.payload.tab);
                    }
                    return [...tabLine];
                })
            };

Это мой код на данный момент но раньше я использовал не useState и не хранил там текущий обьект с данными а просто при клике на саму вкладку менял модель внутри эдитора своего таба. Мне хотя бы найти причину ошибок

I want to rotate WebXR Rectile towards walls

I am new in ARCore and i create a WebXR application with the help of codelab and it works fine but it placed the rectile towards floor i want this rectile should be on wall.

<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Building an augmented reality application with the WebXR Device API</title>
    <link rel="stylesheet" href="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css">
    <script src="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.js"></script>

    <!-- three.js -->
    <script src="https://unpkg.com/[email protected]/build/three.js"></script>
    <script src="https://unpkg.com/[email protected]/examples/js/loaders/GLTFLoader.js"></script>

    <link rel="stylesheet" type="text/css" href="app.css" />
    <script src="utils.js"></script>
  </head>
  <body>
    <div id="enter-ar-info" class="mdc-card demo-card">
      <h2>Augmented Reality with the WebXR Device API</h2>
      <p>
        This is an experiment using augmented reality features with the WebXR Device API.
        Upon entering AR, you will be surrounded by a world of cubes.
        Learn more about these features from the <a href="https://codelabs.developers.google.com/codelabs/ar-with-webxr">Building an augmented reality application with the WebXR Device API</a> Code Lab.
      </p>

      <!-- Starting an immersive WebXR session requires user interaction. Start the WebXR experience with a simple button. -->
      <a id="enter-ar" class="mdc-button mdc-button--raised mdc-button--accent">
        Start augmented reality
      </a>
    </div>

    <div id="unsupported-info" class="mdc-card demo-card">
      <h2>Unsupported Browser</h2>
      <p>
        Your browser does not support AR features with WebXR. Learn more about these features from the
        <a href="https://codelabs.developers.google.com/codelabs/ar-with-webxr">Building an augmented reality application with the WebXR Device API</a> Code Lab.
      </p>
    </div>
    <script src="app.js"></script>
    <div id="stabilization"></div>
  </body>
</html>
/*
 * Copyright 2017 Google Inc. All Rights Reserved.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Query for WebXR support. If there's no support for the `immersive-ar` mode,
 * show an error.
 */
(async function() {
  const isArSessionSupported = navigator.xr && navigator.xr.isSessionSupported && await navigator.xr.isSessionSupported("immersive-ar");
  if (isArSessionSupported) {
    document.getElementById("enter-ar").addEventListener("click", window.app.activateXR)
  } else {
    onNoXRDevice();
  }
})();

/**
 * Container class to manage connecting to the WebXR Device API
 * and handle rendering on every frame.
 */
class App {
  /**
   * Run when the Start AR button is pressed.
   */
  activateXR = async () => {
    try {
      // Initialize a WebXR session using "immersive-ar".
      this.xrSession = await navigator.xr.requestSession("immersive-ar", {
        requiredFeatures: ['hit-test', 'dom-overlay'],
        domOverlay: { root: document.body }
      });

      // Create the canvas that will contain our camera's background and our virtual scene.
      this.createXRCanvas();

      // With everything set up, start the app.
      await this.onSessionStarted();
    } catch(e) {
      console.log(e);
      onNoXRDevice();
    }
  }

  /**
   * Add a canvas element and initialize a WebGL context that is compatible with WebXR.
   */
  createXRCanvas() {
    this.canvas = document.createElement("canvas");
    document.body.appendChild(this.canvas);
    this.gl = this.canvas.getContext("webgl", {xrCompatible: true});

    this.xrSession.updateRenderState({
      baseLayer: new XRWebGLLayer(this.xrSession, this.gl)
    });
  }

  /**
   * Called when the XRSession has begun. Here we set up our three.js
   * renderer, scene, and camera and attach our XRWebGLLayer to the
   * XRSession and kick off the render loop.
   */
  onSessionStarted = async () => {
    // Add the `ar` class to our body, which will hide our 2D components
    document.body.classList.add('ar');

    // To help with working with 3D on the web, we'll use three.js.
    this.setupThreeJs();

    // Setup an XRReferenceSpace using the "local" coordinate system.
    this.localReferenceSpace = await this.xrSession.requestReferenceSpace('local');

    // Create another XRReferenceSpace that has the viewer as the origin.
    this.viewerSpace = await this.xrSession.requestReferenceSpace('viewer');
    // Perform hit testing using the viewer as origin.
    this.hitTestSource = await this.xrSession.requestHitTestSource({ space: this.viewerSpace });

    // Start a rendering loop using this.onXRFrame.
    this.xrSession.requestAnimationFrame(this.onXRFrame);

    this.xrSession.addEventListener("select", this.onSelect);
  }

  /** Place a sunflower when the screen is tapped. */
  onSelect = () => {
    if (window.sunflower) {
      const clone = window.sunflower.clone();
      clone.position.copy(this.reticle.position);
      this.scene.add(clone)

      const shadowMesh = this.scene.children.find(c => c.name === 'shadowMesh');
      shadowMesh.position.y = clone.position.y;
    }
  }

  /**
   * Called on the XRSession's requestAnimationFrame.
   * Called with the time and XRPresentationFrame.
   */
  onXRFrame = (time, frame) => {
    // Queue up the next draw request.
    this.xrSession.requestAnimationFrame(this.onXRFrame);

    // Bind the graphics framebuffer to the baseLayer's framebuffer.
    const framebuffer = this.xrSession.renderState.baseLayer.framebuffer
    this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, framebuffer)
    this.renderer.setFramebuffer(framebuffer);

    // Retrieve the pose of the device.
    // XRFrame.getViewerPose can return null while the session attempts to establish tracking.
    const pose = frame.getViewerPose(this.localReferenceSpace);
    if (pose) {
      // In mobile AR, we only have one view.
      const view = pose.views[0];

      const viewport = this.xrSession.renderState.baseLayer.getViewport(view);
      this.renderer.setSize(viewport.width, viewport.height)

      // Use the view's transform matrix and projection matrix to configure the THREE.camera.
      this.camera.matrix.fromArray(view.transform.matrix)
      this.camera.projectionMatrix.fromArray(view.projectionMatrix);
      this.camera.updateMatrixWorld(true);

      // Conduct hit test.
      const hitTestResults = frame.getHitTestResults(this.hitTestSource);

      // If we have results, consider the environment stabilized.
      if (!this.stabilized && hitTestResults.length > 0) {
        this.stabilized = true;
        document.body.classList.add('stabilized');
      }
      if (hitTestResults.length > 0) {
        const hitPose = hitTestResults[0].getPose(this.localReferenceSpace);

        // Update the reticle position
        this.reticle.visible = true;
        this.reticle.position.set(hitPose.transform.position.x, hitPose.transform.position.y, hitPose.transform.position.z)
        this.reticle.updateMatrixWorld(true);
      }

      // Render the scene with THREE.WebGLRenderer.
      this.renderer.render(this.scene, this.camera)
    }
  }

  /**
   * Initialize three.js specific rendering code, including a WebGLRenderer,
   * a demo scene, and a camera for viewing the 3D content.
   */
  setupThreeJs() {
    // To help with working with 3D on the web, we'll use three.js.
    // Set up the WebGLRenderer, which handles rendering to our session's base layer.
    this.renderer = new THREE.WebGLRenderer({
      alpha: true,
      preserveDrawingBuffer: true,
      canvas: this.canvas,
      context: this.gl
    });
    this.renderer.autoClear = false;
    this.renderer.shadowMap.enabled = true;
    this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;

    // Initialize our demo scene.
    this.scene = DemoUtils.createLitScene();
    this.reticle = new Reticle();
    this.scene.add(this.reticle);

    // We'll update the camera matrices directly from API, so
    // disable matrix auto updates so three.js doesn't attempt
    // to handle the matrices independently.
    this.camera = new THREE.PerspectiveCamera();
    this.camera.matrixAutoUpdate = false;
  }
};

window.app = new App();

I want to place rectile towards wall not on floor my example work very well on floor but it is not working towards wall. How to place object on wall?

How to properly Handle Simultaneous Keyboard Input in a Fast Paced Shooter Game

I have this Keyboard input code. Movement works fine, but the problem is with for example when I’m holding the spacebar key down and trying to shoot while dodging at the same time. Sometimes it will play, more often than not it won’t. How can I handle this? Here’s my code:

const KEYS = {
  W: "w",
  A: "a",
  S: "s",
  D: "d",
  ARROW_UP: "arrowup",
  ARROW_LEFT: "arrowleft",
  ARROW_DOWN: "arrowdown",
  ARROW_RIGHT: "arrowright",
  SPACE: " ",
  TAB: "tab"
};

let keys = {
  [KEYS.W]: false,
  [KEYS.A]: false,
  [KEYS.S]: false,
  [KEYS.D]: false
};

function handleKeyPress(event) {
  const pressedKey = event.key.toLowerCase();
  switch (pressedKey) {
    case KEYS.W:
    case KEYS.ARROW_UP:
      keys[KEYS.W] = true;
      break;
    case KEYS.A:
    case KEYS.ARROW_LEFT:
      keys[KEYS.A] = true;
      break;
    case KEYS.S:
    case KEYS.ARROW_DOWN:
      keys[KEYS.S] = true;
      break;
    case KEYS.D:
    case KEYS.ARROW_RIGHT:
      keys[KEYS.D] = true;
      break;
    case KEYS.TAB:
      event.preventDefault();
    case KEYS.SPACE:
      if (!playerManager.mainPlayer.canShoot || playerManager.mainPlayer.isRespawning) return;
      playerManager.mainPlayer.shoot();
      break;
  }
  // Prevent default behavior for all keys to avoid interference with browser shortcuts
  event.preventDefault();
}

function handleKeyRelease(event) {
  const releasedKey = event.key.toLowerCase();
  switch (releasedKey) {
    case KEYS.W:
    case KEYS.ARROW_UP:
      keys[KEYS.W] = false;
      break;
    case KEYS.A:
    case KEYS.ARROW_LEFT:
      keys[KEYS.A] = false;
      break;
    case KEYS.S:
    case KEYS.ARROW_DOWN:
      keys[KEYS.S] = false;
      break;
    case KEYS.D:
    case KEYS.ARROW_RIGHT:
      keys[KEYS.D] = false;
      break;
  }
}

function handleBlur() {
  keys = {
    [KEYS.W]: false,
    [KEYS.A]: false,
    [KEYS.S]: false,
    [KEYS.D]: false
  };
}

function handlePlayerMovement() {
  if (playerManager.mainPlayer.isRespawning) return;

  const { w, a, s, d } = keys;

  if (w && d) {
    playerManager.mainPlayer.move(Constants.SPEED / 1.25, -Constants.SPEED / 1.25, 45);
  } else if (w && a) {
    playerManager.mainPlayer.move(-Constants.SPEED / 1.25, -Constants.SPEED / 1.25, 135);
  } else if (s && d) {
    playerManager.mainPlayer.move(Constants.SPEED / 1.25, Constants.SPEED / 1.25, -45);
  } else if (s && a) {
    playerManager.mainPlayer.move(-Constants.SPEED / 1.25, Constants.SPEED / 1.25, -315);
  } else if (w) {
    playerManager.mainPlayer.move(null, -Constants.SPEED, 0);
  } else if (a) {
    playerManager.mainPlayer.move(-Constants.SPEED, null, 90);
  } else if (s) {
    playerManager.mainPlayer.move(null, Constants.SPEED, 0);
  } else if (d) {
    playerManager.mainPlayer.move(Constants.SPEED, null, 90);
  }
}

I’d also like to know if this entire code could be written better (incase necessary)

How to update arg in storybook with a function?

I am using a storybook version 8. I have a select component that takes in two arguments: number and function. Function is being called on select change event and should change number argument to a new selected value. How can I do this?

This is storybook story:

const meta = {
  title: 'SelectInput',
  component: SelectInput,
  parameters: {
    layout: 'centered',
  },
  tags: ['autodocs'],
  argTypes: {
    rowsPerPage: {
      control: 'select',
      options: ['5', '10', '15', '25', '50', '75', '100']
    },
    handleChangeRowsPerPage: { onChange: fn()}
  },
} satisfies Meta<typeof SelectInput>;

export default meta;
type Story = StoryObj<typeof meta>;

export const InUse: Story = {
  args: {
    rowsPerPage: 10,
    handleChangeRowsPerPage: (event) => {
      console.log(event.target.value)
    }
  },
};

And this is selectInput component:

function SelectInput({
  rowsPerPage,
  handleChangeRowsPerPage
}: {
  rowsPerPage: number;
  handleChangeRowsPerPage: (event: SelectChangeEvent) => void;
}) {
  return (
    <FormControl className="storybook-select-input">
      <InputLabel id="demo-simple-select-label">Rows per page</InputLabel>
      <Select
        labelId="demo-simple-select-label"
        id="demo-simple-select"
        value={rowsPerPage.toString()}
        label="Rows per page"
        onChange={handleChangeRowsPerPage}
      >
        <MenuItem value={5}>5</MenuItem>
        <MenuItem value={10}>10</MenuItem>
        <MenuItem value={15}>15</MenuItem>
        <MenuItem value={25}>25</MenuItem>
        <MenuItem value={50}>50</MenuItem>
        <MenuItem value={75}>75</MenuItem>
        <MenuItem value={100}>100</MenuItem>
      </Select>
    </FormControl>
  );
}

export default SelectInput;

I have a response from an API in the form of a binary file and I need to transform it into a PDF in react.js

I’ve been trying everything but I can’t generate the PDF properly; either I get a blank PDF or a text file with gibberish characters.

`try {
const response = await getFunc(getUrl, token, header);

  const url = window.URL.createObjectURL(new Blob([response]));

  // Crear un enlace para descargar el PDF
  const link = document.createElement("a");
  link.href = url;
  link.setAttribute("download", "miArchivo.pdf"); // Cambiar a .pdf
  document.body.appendChild(link);
  link.click();

  // Limpieza después de la descarga
  window.URL.revokeObjectURL(url);
  document.body.removeChild(link);
} catch (error) {
  console.error("Error al descargar el certificado:", error);
}`

I need the PDF file

mySQL through docker compose not available at localhost

I deployed mysql via docker compose and it’s available at 0.0.0.0 and at 127.0.0.1 via commands mysql --host=127.0.0.1 --user=root --password=team6 --port=53366 and mysql --host=0.0.0.0 --user=root --password=team6 --port=53366 but mysql --host=localhost --user=root --password=team6 --port=53366 fails due to “ERROR 1045 (28000): Access denied for user ‘root’@’localhost’ (using password: YES)”, why?

My end goal is for this code to work

      con = await mysql.createConnection({
        host:  'localhost',
        port:  '53366', //We need to consider adding new users
        user: 'root',
        password: 'team6',
        database: 'Yahtzee',
      });

My compose file:

# Compose file for creating a database named Yahtzee in a mysql container
version: '3.8'
services:
  team6db:
    image: mysql/mysql-server:latest
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: team6
      MYSQL_DATABASE: Yahtzee
      MYSQL_ROOT_HOST: '%'
    volumes:
      - team6db:/var/lib/mysql
      - ./Initdb.sql:/docker-entrypoint-initdb.d/Initdb.sql
      - ./InsertSampleGameRecords.sql:/docker-entrypoint-initdb.d/InsertSampleGameRecords.sql
    ports:
      - '53366:3306'

  team6phpmyadmin:
    image: phpmyadmin/phpmyadmin:latest
    restart: always
    depends_on:
      - team6db
    environment:
      PMA_HOST: team6db
      PMA_USER: root
      PMA_PASSWORD: team
    ports:
      - '50086:80'

volumes:
  team6db:

How can I update the zooming point when the window is resized in Leaflet map?

I found a code that makes it possible to zoom in center always. But when I resize the window, this center remains the same still, so it zooms in weirdly. I want to update this point when the window is resized.

L.Map.ScrollWheelZoom.include({
    _performZoom: function() {
        var map = this._map,
            zoom = map.getZoom(),
            snap = this._map.options.zoomSnap || 0;

        map._stop();

        var d2 = this._delta / (this._map.options.wheelPxPerZoomLevel * 4),
            d3 = 4 * Math.log(2 / (1 + Math.exp(-Math.abs(d2)))) / Math.LN2,
            d4 = snap ? Math.ceil(d3 / snap) * snap : d3,
            delta = map._limitZoom(zoom + (this._delta > 0 ? d4 : -d4)) - zoom;

        this._delta = 0;
        this._startTime = null;

        if (!delta) {
            return;
        }

        if (map.options.scrollWheelZoom === 'center') {
            console.log(zoom + delta);
            map.setZoom(zoom + delta);

        } else if (map.options.scrollWheelZoom instanceof L.Point) {
            map.setZoomAround(map.options.scrollWheelZoom, zoom + delta);
        
        } else {
            map.setZoomAround(this._lastMousePos, zoom + delta);
        }
    }
});

var map = L.map('map', {
    scrollWheelZoom: L.point(window.innerWidth/2, window.innerHeight/2),
    crs: L.CRS.Simple
});

And I have asked about how to use setZoom() and setView() together in Leaflet, and someone answered my question but I don’t really get it.

Hyperapp with list and clock, want to refresh list every 5 seconds

I’ve got the following code https://pastebin.com/gp4VerFN/
subscriptions:
which fetches a list of names etc from a URL.

It also has a timer, which updates a span with the current time every second.
I’d now like to refresh the list every X seconds but I’m not able to get it to work. Could anyone please explain how its done?

TIA
ps. As this is meant to be used offline I’ve downloaded the hyperapp & time code.

I’ve tried a number of things and even asked chatgpt but no luck.

How do I locally host an Apache Arrow Flight server using Go and retrieve in Javascript?

I’m using Go for my backend server and Javascript as my frontend, I’ve successfully used http previously to localhost some simple data in IPC in Go then fetch and retrieve in my table from the localhost url in Javascript. But now I’m having trouble with trying to setup a way of serving and retrieving data using flight.

So the main part of my question is how do you setup an apache arrow flight server locally on a Go backend(with my arrow.Record being the data sent) and then retrieve this data in a Javascript frontend?

Code from my main.go file setting up the data:

import (
    "fmt"
    "github.com/apache/arrow/go/v16/arrow"
    "github.com/apache/arrow/go/v16/arrow/array"
    "github.com/apache/arrow/go/v16/arrow/flight"
    "github.com/apache/arrow/go/v16/arrow/memory"
    "log"
    "net/http"
)

var metadata = arrow.NewMetadata(
    []string{"type", "round", "date"},
    []string{"int", "1dp", "2024/03/30"},
)

var schema = arrow.NewSchema([]arrow.Field{
    {Name: "X", Type: arrow.PrimitiveTypes.Int32},
    {Name: "X + 5", Type: arrow.PrimitiveTypes.Int32},
}, &metadata)

func GetPutData() arrow.Record {

    pool := memory.NewGoAllocator()

    recordBuilder := array.NewRecordBuilder(pool, schema)

    recordBuilder.Field(0).(*array.Int32Builder).AppendValues([]int32{1, 2, 3, 4, 5}, nil)
    recordBuilder.Field(1).(*array.Int32Builder).AppendValues([]int32{6, 7, 8, 9, 10}, nil)

    record := recordBuilder.NewRecord()

    return record
}

And I imagine my main method to be something like:

func main() {
    // Create a Flight server locally with data from GetPutData
    rec := GetPutData()
    
    // Start flight server

    fmt.Println("Flight serving on port...")
}

Then on the frontend I imagine it would be some code like this:

import * as Arrow from 'apache-arrow';
import * as Flight from 'apache-arrow/flight';

async function runExample(url) {

    const table = // Fetch data from flight server

    console.table(table.toArray());
    console.log(table.schema)
    console.log(table.data)
}

runExample(url);

I’ve tried using previous examples but they appear outdated? But I have also tried looking through the documentation here but I find it incredibly confusing to find what old methods have changed to etc. Also I’m currently not bothered about adding in any authentication.

Why does the value of this keyword value is different on normal function vs calling the function using window object

"use strict"

function hello(){
console.log(this);
}

hello(); // undefined
window.hello(); // window object

I was trying to create a simple hello function to print the value of this keyword on strict mode.
I get undefined on normal function call.
When I call the function using the window object, the value of this keyword is window object.

Curios to know what is happening behind the scenes.

Unhandled Runtime Error TypeError: Cannot read properties of null (reading ‘default’) in my next.js

"use client"
import { useKindeBrowserClient } from '@kinde-oss/kinde-auth-nextjs'
import Image from 'next/image';
import React from 'react'

function DashboardHeader() {

  const {user} = useKindeBrowserClient();
  return (
   <div>
    <Image src={user?.picture} alt='logo'
    width={40}
    height={40}
    /> 
   </div>
  )
}

export default DashboardHeader

I am getting this error in my webapp, I m getting this error because of image tag in the provided code.

I have noticed once I remove this image tag code, everything works fine. But the moment I write this image tag code, this issue pop up.

I tried everything but can’t solve. Please help someone ASAP

Qualtrics: Page does not start at the top

When the page overflows, that is when not everything on the page can be displayed without any scrolling, then the page automatically jumps to the question part of the survey page. Is there a way to prevent this with Javascript or CSS so that every page in the survey starts from the top?

I already tried to add this code to the JS of the questions:

Qualtrics.SurveyEngine.addOnload(function() {
window.scrollTo(0,0);
});

but unfortunately it did not work.