Creating a functional calculator with React [duplicate]

I’m a beginner in this. I’m studying in a bootcamp, and teacher sent me to create a functional calculator with React. Almost everything I created at this moment in this project it works well. The only thing I don’t understand, it’s why if I’m using variables with the hook useState() sometimes they don’t update properly… I would understand if I use normal variables with const or let but I used with useState() for that, for having updating variables.

So my main problem is the updating of variables. I asked help to AIs but all solutions were incorrect so I don’t know what more things to try.

Here my code, don’t judge me pls, I’m a beginner like I said:

import React, { useState } from 'react'

const Calculator2 = () => {

    const [firstNumber, setFirstNumber] = useState("")
    const [secondNumber, setSecondNumber] = useState("")
    const [operator, setOperator] = useState("")
    const [operatorActivated, setOperatorActivated] = useState(false)
    const [finalResult, setFinalResult] = useState("")

    // OPERATION FUNCTIONS
    function sum(a,b) {
        return a + b
    }
    function subtract(a,b) {
        return a - b
    }
    function multiply(a,b) {
        return a * b
    }
    function divide(a,b) {
        return a / b
    }
    function divideByOneHundred(a) {
        return a / 100
    }

    const checkResult = () => {
        if(operatorActivated && finalResult !== "") {
            setFirstNumber(finalResult)
        }
        setFinalResult("");
    }

    const calculateResult = () => {
        const number1 = parseFloat(firstNumber)
        const number2 = parseFloat(secondNumber)
        let result = 0
        switch(operator){
            case "+": 
                result = sum(number1, number2); 
                break;
            case "-": 
                result = subtract(number1, number2); 
                break;
            case "x": 
                result = multiply(number1, number2); 
                break;            
            case "/": 
                result = divide(number1, number2); 
                break;
            case "%": 
                result = divideByOneHundred(number1); 
                break;
        }
        setFirstNumber("")
        setOperator("")
        setSecondNumber("")
        setFinalResult(String(result)) 
        setOperatorActivated(false)
        console.log(finalResult); // HERE I DON'T KNOW WHY, THE VALUE IS AN EMPTY STRING
    }

    const handleInput = (value) => {
        checkResult()
        if(!operator) {
            setFirstNumber(firstNumber + value)
        } else {
            setSecondNumber(secondNumber + value)
        }
    }

    const handleOperator = (simbol) => {
        setOperatorActivated(true)
        checkResult()
        setOperator(simbol)
    }

    const resetCalculator = () => {
        setFirstNumber("")
        setOperator("")
        setSecondNumber("")
        setFinalResult("")
    }
    console.log(finalResult); // HERE I CAN SEE THE REAL VALUE
  return (
    <>
        <input type="text" className="show-result form-control mt-5 mx-1 bg-light" readOnly value={`${firstNumber}${operator}${secondNumber}${finalResult}`}/>
        <button onClick={()=> handleInput("1")} className="digits text-center m-1 fw-semibold">1</button>
        <button onClick={()=> handleInput("2")} className="digits text-center m-1 fw-semibold">2</button>
        <button onClick={()=> handleInput("3")} className="digits text-center m-1 fw-semibold">3</button>
        <button onClick={()=> handleInput("4")} className="digits text-center m-1 fw-semibold">4</button>
        <button onClick={()=> handleInput("5")} className="digits text-center m-1 fw-semibold">5</button>
        <button onClick={()=> handleInput("6")} className="digits text-center m-1 fw-semibold">6</button>
        <button onClick={()=> handleInput("7")} className="digits text-center m-1 fw-semibold">7</button>
        <button onClick={()=> handleInput("8")} className="digits text-center m-1 fw-semibold">8</button>
        <button onClick={()=> handleInput("9")} className="digits text-center m-1 fw-semibold">9</button>
        <button onClick={()=> handleOperator("+")} className="digits text-center m-1 fw-semibold">+</button>
        <button onClick={()=> handleOperator("-")} className="digits text-center m-1 fw-semibold">-</button>
        <button onClick={()=> handleOperator("x")} className="digits text-center m-1 fw-semibold">x</button>
        <button onClick={()=> handleOperator("/")} className="digits text-center m-1 fw-semibold">/</button>
        <button onClick={()=> handleOperator("%")} className="digits text-center m-1 fw-semibold">%</button>
        <button onClick={calculateResult} className="digits text-center m-1 fw-semibold">=</button>
        {!finalResult ? 
        <button onClick={resetCalculator} className="digits text-center m-1 fw-semibold">C</button>
        : <button onClick={resetCalculator} className="digits text-center m-1 fw-semibold">AC</button>
        }
    </>  
)
}

export default Calculator2

Almost everything works but When I push the key “=”, the function calculateResult() is activated and you can see in the inpout the result, it’s okay but in the console the result (finalResult variable) is an empty string… so weird and I want after that if the user push a number, the result disappear and number is saved in firstNumber. And if the user push a operator is because they want to use this result to do another operation so I saved the value of finalResult in firstNumber and I clear finalResult. I do all of this in checkResult() function but like the value of finalResult is an empty string, an empty string is saved in firstNumber and everything break. The AIs told me to use the hook useEffect() but my teacher asked me to do without it so I donĀ“t know what more I could do. I’d understand that problem if I was using normal variables but why variables are not updated using variables with memory with useState()?

Please help me.

Thank you very much.

Is there any way to use Cypress for unit testing functions? (React Framework)

I am trying to test helper functions of my application using cypress, but I am not sure if it is possible, or how I could make it work. I know cypress it meant to be used for e2e and component testing, but it seems like there could be a way to make it work for functions too. I’m trying to move away from Jest because Jest is incompatible with react 18. There is also a memory leak issue between node and jest which it seems I can’t fix because create-react-app does not allow us to use the configuration settings to patch the leak.

For example if I have a file called helpers.js (I’ve simplified the functions for readability)

export const sum = (a, b) => a+b
export const subtract = (a, b) => a-b

I want to be able to import and test these functions in cypress. I thought it might look something like:

import * as helpers from 'helpers.js';

context('Helpers', () => {
    describe('sum', () => {
    it('should add the values correctly', () => {
        const result = helpers.sum(1, 2);
        expect(result).to.equal(3);
    });
    });
});

I have also tried creating cypress commands and using those in the tests

import { sum } from 'helpers.js'
Cypress.Commands.add('sum', (a, b) => sum(a, b))
context('Helpers', () => {
    describe('sum', () => {
    it('should add the values correctly', () => {
        const result = cy.sum(1, 2);
        expect(result).to.equal(3);
    });
    });
});

However both scenarios result in an error of Cannot access 'subtract' before initialization. If anyone has any insight, it would be greatly appreciated!

Uploading Files to Firebase in JavaScript

I am unsure why my uploadFile function is not working. When ran there are no errors and the console indicates everything is working as intended, however when I check my database there are no new files after an upload attempt.

”’

// uploadFiles event listener
const uploadFiles = document.getElementById("uploadFile");
    uploadFiles.addEventListener("click", (e) => {
      uploadFile()
        .catch((err) => {
          console.log(err.message);
        });
    });


async function uploadFile() {
  console.log("executed");
  const fileInput = document.getElementById('fileInput');
  if (!fileInput) {
    console.error("File input element not found.");
    return;
  }
  const file = fileInput.files[0];

  if (!file) {
    console.error("No file selected.");
    return;
  }

  try {
    const storeRef = ref(storage, `Taps/${file.name}`);
    const snapshot = await uploadBytesResumable(storeRef, file);
    console.log('uploaded image');

  } catch (error) {
    console.error("Upload error:", error);
  }
}

”’

Cannot import mp4 filetypes with webpack

I’ve seen other solutions related to this issue, but none seem to work for me. I’m trying to import an mp4 file using webpack but I get the error that there are no loaders configured to process my file. I import the file like so:

import videoSrcInit from (‘../src/ImageSlider/slider_1.mp4’);

Here’s my webpack.config.js file:

const path = require('path');
module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'main.js',
        path: path.resolve(__dirname, 'dist'),
        assetModuleFilename: '[name][ext]',
    },
    module: {
        rules: [
            {
                test: /.css$/i,
                use: ['style-loader', 'css-loader'],
            },
            {
                test: /.(pdf|png|svg|jpg|jpeg|gif)$/i,
                type: 'asset/resource',
            },
            {
                test: /.(woff|woff2|eot|ttf|otf)$/i,
                type: 'asset/resource',
            },
            {
                test: /.(mov|mp4)$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: '[name].[ext]'
                        }
                    }
                ]
            },
            {
                test: /.html$/,
                exclude: /node_modules/,
                use: [
                    {
                        loader: "html-loader",
                        options: {
                            sources: {
                                list: [
                                    {
                                        tag: "source",
                                        attribute: "src",
                                        type: "src"
                                    }
                                ]
                            }
                        }
                    }
                ]
            }
        ]
    }

};```

What I added above was from this solution: https://stackoverflow.com/questions/49943372/load-video-mp4-webpack-loader 
Unfortunately still not working for me.

Resend email doesn’t work in production environement with next js, but works in development

import { EmailTemplate } from "@/components/email-template";
import { Resend } from "resend";

const resend = new Resend("myApiKey"); // this works only in dev
// const resend = new Resend(process.env.NEXT_PUBLIC_RESEND_API_KEY); // this doesnt at all
// const resend = new Resend(process.env.RESEND_API_KEY); // this doesnt at all


export async function POST(request: Request) {
  const { name, numberPhone, address, productsInCart} = await request.json();

  try {
    const data = await resend.emails.send({
      from: "Contact Form <[email protected]>",
      to: ["[email protected]"],
      subject: "New order from your ecommerce app.",
      react: EmailTemplate({
        name: name,
        numberPhone: numberPhone,
        address: address,
        productsInCart: productsInCart
      }),
    });

    return Response.json(data);
  } catch (error) {
    return Response.json({ error });
  }
}

Tried both process.env.RESEND_API_KEY and EXT_PUBLIC_RESEND_API_KEY
I have the variable in env.local file

The crazy thing that it works on development but not in vercel production deployment
i want this to work when it’s deployed as well

Persevering a dark mode button

A beginner at JScript here and have a custom light / dark mode button, which i’d like to persevere and remain in the mode it was clicked in (as currently resets to default on page reload and have to keep manually changing). I think I need to add a local storage element to the script but not sure how… my snippet for the button control is below – the controller is a css element i have as a custom button and have included the dark css elements. If i’ve missed providing anything, please let me know. Any help would be much appreciated..

```
<script>//.....
//other code......

var controlHandler = function() {
  document.body.classList.toggle("dark");
  if (document.body.classList.contains("dark")) {
    controller.textContent = "go LIGHT";
  } else {
    controller.textContent = "go DARK";
  }
};

// Control Trigger
var controller = document.querySelector(".controller");
controller.addEventListener("click", controlHandler);

</script>
```



body.dark {
background: rgba(0, 0, 0, 0.9)!important;
}
body.dark .ripple {
background: rgba(255, 255, 255, 0.5);
}
body.dark .controller {
color: rgba(255, 255, 255, 0.9);
border-color: rgba(255, 255, 255, 0.9);

Tried asking chatGPT but it just messed up my script while adding a localstorage query and couldn’t get it scripted correctly to work. I needed to keep the dark toggle setup to keep the custom button working the toggle. Tried looking at dark mode questions here but none to fit my case or not sure how.

How to implent logic for deleting single task Todo app?

export function delTask(taskContainer) {
    const id = taskContainer.id
    const title = taskContainer.title
    let keyFound = false;
    const numItems = localStorage.length
    for(let i = numItems - 1; i >= 0; i--) {
        const key = localStorage.key(i)
        const value = localStorage.getItem(key)
       console.log("key" + key + " " + "id" + id)
       console.log(keyFound)
       if(keyFound) {
           let keyCount = key.substring(6 + title.length)
           keyCount = parseInt(keyCount) + 1
           if(key.startsWith("task_") && key.includes(title)) {
            const noCountKey = key.slice(0, -1)
            const newKey = noCountKey + keyCount
            localStorage.removeItem(key)
            localStorage.setItem(newKey, value)
            console.log(newKey)

        }

    }
    if(id.toString() === key.toString()) {
        keyFound = true
        console.log("keyis found" + keyFound)
        localStorage.removeItem(key)
        
    }

}

}

Been stuck trying to debug this code I think there could be a logic flaw the idea is that local storage would contain something like this

project_project 1 2222-02-22dfwqfdqwd task_project 1_0 task 1 task_project 1_1 task 2 task_project 1_2 task 3 task_project 1_3 task 4

And the parameter contains the parent element of the delete button and it will go through each item in the local storage if it matches the parent element it will change key to true and delete that task, after that it goes through the other tasks with the same title and subtracts 1 from end of the key and makes a new one

If I delete the third task I get this in local storage
task_project 1_1 task 2 task_project 1_-1 task 1 task_project 1_NaN 2222-02-22dfwqfdqwd task_project 1_2 task 4

I am new to programming and am doing this for the Odin project any other approaches or a fix is greatly appreciated.

Character atlas/spritesheet animation with user input not stopping on key up Phaser 3

I’m working on animating a character (using a texture atlas) with user input in Phaser 3 and I’m running into an issue with the animation not stopping when I release the respective arrow button. I’ve tried a few tactics, and some of them only partially work. The code below is what I use which works as intended in all respects, except the animation doesn’t stop after I release the respective arrow key. Maybe I need logic with stopping animation once the key is lifted? Any suggestions? Thanks!

update() {      

    this.hero.setVelocity(0,0);

    if (this.cursors.up.isDown) {
        this.hero.anims.play('walkUp', true); 
        this.hero.setVelocityY(-200);                     
    } 
    
    else if (this.cursors.down.isDown) {
        this.hero.anims.play('walkDown', true) 
        this.hero.setVelocityY(200);
    }         

    if (this.cursors.left.isDown) {    
        this.hero.anims.play('walkLeft', true)
        this.hero.setVelocityX(-200);
    } 

    else if (this.cursors.right.isDown) {
        this.hero.anims.play('walkRight', true)
        this.hero.setVelocityX(200);
    }                
}

SpeechSynthesis.speak doesn’t start without user interaction

has anyone solved the problem of how to start audio play without user interaction using speechSynthesis.speak? (Firefox 124.0.1 (64 bit) seems to work fine, on Chrome 123.0.6312.59 (64 bit) doesn’t work).

This works fine on Firefox but not in Chrome:

window.speechSynthesis.speak(Object.assign(new SpeechSynthesisUtterance('Hallo Bob'), {
  voice: window.speechSynthesis.getVoices().find(v => v.lang === 'de-DE' && v.name == "Anna")
}))

Thanks.

Iterate each cell with ExcelJS

I having trouble when I try to export an Excel with data al ready filled, this is the error message on console:

enter image description here

The total of results are 346880 with 28 headers that makes a total of 9,712,640 cells, and put so many console.log() too see better what’s the real problema and end in this loop:

 headerRow.eachCell((cell, colNumber) => {
          cell.fill = { type: 'pattern', 
                        pattern: 'solid', 
                        fgColor: { argb: 'D9D9D9' } };
          cell.border = { top: { style: 'thin' }, 
                          left: { style: 'thin' }, 
                          bottom: { style: 'thin' }, 
                          right: { style: 'thin' } };
      
          const column = worksheet.getColumn(colNumber);
          const headerText = cell.text || '';
          const maxTextLength = Math.max(
            ...data.map(item => (item[colNumber - 1] || '').toString().length + headerText.length)
          );

          column.width = maxTextLength + 2;
        });

I try something like this:

const maxTextLengths [] = [];
for (let colNumber = 1; colNumber <= headerRow.cellCount; colNumber++) {
const headerText = headerRow.getCell(colNumber).text || '';
const maxLength = Math.max(
...data.map(item => (item[colNumber - 1] || '').toString().length + headerText.length)
);
maxTextLengths.push(maxLength);
}

headerRow.eachCell((cell, colNumber) => {
cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'D9D9D9' } };
cell.border = { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' } };

const column = worksheet.getColumn(colNumber);
column.width = maxTextLengths[colNumber - 1] + 2;
});

But got the same issue.

React Native Firestore : how to change the button background by available(the data is not on database) or not available(the data is in database)

I already fetch the data but i don’t know how to turn the time button background from orange(the data isn’t on database) to grey(the data is on database), do i need to change my availableTimes or put another condition on my code ? Thank Your Very Muchh

collection booking
field :
1. createdAt
2. time (value: timestamp)

what this app needs now is:

on touchableopacity fetch day month day and year
on touchablewithoutfeedback fetch only hours

import React, {useState, useEffect} from 'react';
import {
  Text,
  View,
  StyleSheet,
  Dimensions,
  ScrollView,
  Alert,
  TouchableOpacity,
  TouchableWithoutFeedback,
  StatusBar,
  ImageBackground,
} from 'react-native';
import {
  BORDERRADIUS,
  COLORS,
  FONTFAMILY,
  FONTSIZE,
  SPACING,
} from '../theme/theme';
import firestore from '@react-native-firebase/firestore';
import DateTimePicker from '@react-native-community/datetimepicker';
import moment from 'moment';
import CustomIcon from '../components/CustomIcon';
import LinearGradient from 'react-native-linear-gradient';
import AppHeader from '../components/AppHeader';

const windowHeight = Dimensions.get('window').height;
const windowWidth = Dimensions.get('window').width;

const ShowScheduleScreen = ({navigation, route}: any) => {
  const [fieldData, setFieldData] = useState([]);
  const [date, setDate] = useState(moment().tz('Asia/Singapore').toDate());
  const [showDatePicker, setShowDatePicker] = useState(false);
  const [bookingData, setBookingData] = useState([]);
  const availableTimes = [
    new Date(0, 0, 0, 10, 0, 0),
    new Date(0, 0, 0, 11, 0, 0),
    new Date(0, 0, 0, 12, 0, 0),
    new Date(0, 0, 0, 13, 0, 0),
    new Date(0, 0, 0, 14, 0, 0),
    new Date(0, 0, 0, 15, 0, 0),
    new Date(0, 0, 0, 16, 0, 0),
    new Date(0, 0, 0, 17, 0, 0),
    new Date(0, 0, 0, 18, 0, 0),
    new Date(0, 0, 0, 19, 0, 0),
    new Date(0, 0, 0, 20, 0, 0),
    new Date(0, 0, 0, 21, 0, 0),
    new Date(0, 0, 0, 22, 0, 0),
    new Date(0, 0, 0, 23, 0, 0),
  ];

  const selectedFieldId = route.params?.fieldid;
  const selectedField = fieldData.find(
    item => item.id_lapangan === selectedFieldId,
  );
  const fetchFieldData = async () => {
    try {
      const querySnapshot = await firestore()
        .collection('lapangan')
        .orderBy('created_at')
        .get();
      const data: any = querySnapshot.docs.map(doc => {
        const document = doc.data();
        document.id_lapangan = doc.id;
        document.image = document.image ? document.image : '';
        return document;
      });
      setFieldData(data);
    } catch (error) {
      console.log('Error fetching field data:', error);
    }
  };

  const fetchBookingData = async () => {
    try {
      const querySnapshot = await firestore()
        .collection('booking')
        .where('id_lapangan', '==', selectedFieldId)
        .get();
      const data: any = querySnapshot.docs.map(doc => {
        const document = doc.data();
        return document;
      });
      setBookingData(data);
      console.log(data);
    } catch (error) {
      console.log('Error fetching booking data:', error);
    }
  };

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

  useEffect(() => {
    if (selectedFieldId) {
      fetchBookingData();
    }
  }, [selectedFieldId, date]);

  const handleDateChange = (event: any, selectedDate: any) => {
    const currentDate = selectedDate || date;
    setShowDatePicker(false);

    const selectedDateTime = moment(currentDate).tz('Asia/Singapore');
    const selectedDateOnly = selectedDateTime.format('YYYY-MM-DD');

    const today = moment().tz('Asia/Singapore');
    const normalizedCurrentDate = moment(selectedDateOnly).startOf('day');
    const normalizedToday = moment(today).tz('Asia/Singapore').startOf('day');

    if (normalizedCurrentDate.isBefore(normalizedToday)) {
      Alert.alert('Tanggal tidak valid', 'Tolong pilih tanggal yang valid');
      return;
    }

    setDate(selectedDateTime.toDate());
  };

  return (
    <ScrollView style={styles.container}>
      <StatusBar hidden />
      <View>
        <ImageBackground
          source={{uri: selectedField?.image}}
          style={[
            styles.imageBG,
            {aspectRatio: 2372 / 1727, height: windowWidth * (1727 / 2372)},
          ]}>
          <LinearGradient
            colors={[COLORS.BlackRGB10, COLORS.Black]}
            style={styles.linearGradient}>
            <View style={styles.appHeaderContainer}>
              <AppHeader
                leftIcon="close"
                leftAction={() => navigation.goBack()}
              />
            </View>
          </LinearGradient>
        </ImageBackground>
      </View>
      <View style={styles.wrapper}>
        <View style={styles.containerX}>
          <Text style={styles.dateInfoText}>Pilih Tanggal</Text>
          <TouchableOpacity
            style={styles.touchableInputX}
            onPress={() => setShowDatePicker(true)}>
            <Text style={styles.touchableInputTextX}>
              {moment(date)
                .tz('Asia/Singapore')
                .locale('id')
                .format('dddd, DD MMMM YYYY')}
            </Text>
          </TouchableOpacity>
          {showDatePicker && (
            <DateTimePicker
              value={moment(date).tz('Asia/Singapore').toDate()}
              mode="date"
              locale="id-ID"
              display="spinner"
              onChange={handleDateChange}
            />
          )}
        </View>
        <View style={styles.buttonContainer}>
          {Array.from(Array(4), (_, row) => (
            <View style={styles.row} key={`row_${row}`}>
              {Array.from(Array(row === 0 || row === 3 ? 3 : 4), (_, col) => {
                let index;
                if (row === 0) {
                  index = col;
                } else if (row === 1) {
                  index = 3 + col;
                } else if (row === 2) {
                  index = 7 + col;
                } else if (row === 3) {
                  index = 11 + col;
                }
                if (index < availableTimes.length) {
                  const time = availableTimes[index];
                  return (
                    <TouchableWithoutFeedback
                      key={`button_${index}`}
                      disabled={true}>
                      <View style={styles.button}>
                        <Text style={styles.buttonText}>
                          {time.getHours()}:00
                        </Text>
                      </View>
                    </TouchableWithoutFeedback>
                  );
                } else {
                  return null;
                }
              })}
            </View>
          ))}
        </View>
        <View style={styles.timeRadioContainer}>
          <View style={styles.radioContainer}>
            <CustomIcon
              name="radio"
              style={[styles.radioIcon, {color: COLORS.Orange}]}
            />
            <Text style={styles.radioText}>Tersedia</Text>
          </View>
          <View style={styles.radioContainer}>
            <CustomIcon
              name="radio"
              style={[styles.radioIcon, {color: COLORS.Grey}]}
            />
            <Text style={styles.radioText}>Tidak Tersedia</Text>
          </View>
        </View>
      </View>
    </ScrollView>
  );
};

const styles = StyleSheet.create({
  container: {
    height: '100%',
    backgroundColor: COLORS.Black,
  },
  containerX: {
    flex: 1,
    justifyContent: 'center',
    position: 'relative',
    marginVertical: SPACING.space_16,
  },
  appHeaderContainer: {
    marginHorizontal: SPACING.space_36,
    marginTop: SPACING.space_20 * 2,
  },
  imageBG: {
    width: '100%',
    aspectRatio: 3072 / 1727,
  },
  linearGradient: {
    height: '100%',
  },
  buttonContainer: {
    marginTop: SPACING.space_4,
    flexDirection: 'column',
    alignItems: 'center',
  },
  wrapper: {
    marginVertical: SPACING.space_32,
  },
  touchableInputX: {
    borderWidth: 2,
    borderColor: COLORS.White,
    backgroundColor: COLORS.Orange,
    borderRadius: BORDERRADIUS.radius_10,
    marginHorizontal: 40,
    paddingVertical: SPACING.space_10,
    fontSize: FONTSIZE.size_16,
    justifyContent: 'center',
  },
  touchableInputTextX: {
    fontFamily: FONTFAMILY.poppins_semibold,
    fontSize: FONTSIZE.size_16,
    color: COLORS.White,
    textAlign: 'center',
  },
  dateInfoText: {
    fontFamily: FONTFAMILY.poppins_regular,
    fontSize: FONTSIZE.size_14,
    color: COLORS.White,
    marginBottom: SPACING.space_4,
    marginLeft: SPACING.space_28,
  },
  containerGap: {
    gap: SPACING.space_36,
  },
  row: {
    flexDirection: 'row',
    marginBottom: 10,
  },
  button: {
    width: windowWidth * 0.18,
    height: 30,
    marginHorizontal: 5,
    justifyContent: 'center',
    alignItems: 'center',
    borderRadius: BORDERRADIUS.radius_10,
    borderColor: COLORS.White,
    borderWidth: 2,
    backgroundColor: COLORS.Orange,
  },
  buttonText: {
    fontFamily: FONTFAMILY.poppins_semibold,
    fontSize: FONTSIZE.size_14,
    color: COLORS.White,
  },
  timeRadioContainer: {
    flexDirection: 'row',
    marginTop: SPACING.space_4,
    marginBottom: SPACING.space_10,
    alignItems: 'center',
    justifyContent: 'space-evenly',
  },
  radioContainer: {
    flexDirection: 'row',
    gap: SPACING.space_10,
    alignItems: 'center',
  },
  radioIcon: {
    fontSize: FONTSIZE.size_20,
    color: COLORS.White,
  },
  radioText: {
    fontFamily: FONTFAMILY.poppins_medium,
    fontSize: FONTSIZE.size_12,
    color: COLORS.White,
  },
});

export default ShowScheduleScreen;

Phaser 3 console.log() tile properties for a specific game character

anyone can suggest on a general level how to achieve following with Phaser 3:

I need to be able to console.log() in an updated manner the tile or terrain properties enemy sprite is on. Idea is to update character animation if its on water or land. I tried to console.log(this.streetLayer.getTileAtWorldXY(this.enemy.x, this.enemy.y, true); but world map is undefined in the update() method.. Or is there easier way of achieving this? My game is a top down RPG.

Line break React

I’m very new to coding. I have looked over MDN, WJ(something). I can’t figure out how to put a line break

         return market.outcomes.map(
                                  ({ name, price, point }) => {
                                    let sbTemp = "";

                                    if (name === "Over") {
                                      sbTemp = "o";
                                    } else if (name === "Under") {
                                      sbTemp = "u";
                                    }

                                    if (point && point !== "price") {
                                      sbTemp += `${point}`;
                                    }
                                    sbTemp += price;

                                    return <td>{sbTemp}</td>;
                                  }
                                );
                              })}
                            </tr>`your text`

Like i said I tried to to use MDN, WJ3. <br>, n. not understanding