Why is my code not running in my for await function

So I am calling this function from a useEffect hook in React Native, the issue is within the function as the function contains a for await loop. The console.log outside the function works but all of the code inside the for await doesn’t run. how do I fix this?

Here is the function:

const addBook = async () => {
    console.log('IT IS HAPPENING!!!! 2');
    for await (const book of selectedBooks) {
      console.log('IT IS HAPPENING!!!! 3');
      setIdSearchValue(book.id);
      console.log('ID SREARCH VALUE', book.id);
      console.log(' ~ screenTransfer ~ selectedBooks[i].id:', book.id);
      await getBooksQuery.refetch(); // Wait for data to be fetched
      console.log('ENABLE BOOKS QUERY VALUE', enableBooksQuery);
      console.log('GETBOOOKSQUERYDATA', getBooksQuery.data);
      console.log('GETBOOOKSQUERYERROR', getBooksQuery.isError, getBooksQuery.error);
    }
  };

I tried switching the for await to a regular for loop with the same await but it still doesn’t work. I am Expecting to see all of the console.logs in the for await to be ran.

Unable to parse JSON due to format of numerical value [closed]

I am trying to convert JSON to an object via JSON.parse(`{${jsonStr.replace()}}`), is my case value of the {${jsonStr.replace()}} is

{ "MIA": 246, "liberty": 215, "TerminalOrderId": 002539224748 }

Is there any possible way to convert this string from

{ "MIA": 246, "liberty": 215, "TerminalOrderId": 002539224748 }

To

{ "MIA": "246", "liberty": "215", "TerminalOrderId": "002539224748" }

This would allow me to convert JSON to an object without any errors

when conditionally rendering an input component getting this error – A component is changing a controlled input to be uncontrolled

When I am editing the campaign and switching the Welcome Message Type from Text to Audio it throws this error – Warning: A component is changing a controlled input to be uncontrolled. This is likely caused by the value changing from a defined to undefined, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component.

Audio component is a file component –

index.js

import {
  Button,
  Card,
  CardBody,
  CardHeader,
  Col,
  Container,
  Row,
} from "reactstrap";
import BreadCrumb from "../../Components/Common/BreadCrumb";
import { Link } from "react-router-dom";
import AddCampaignModal from "./AddCampaignModal";
import { useFormik } from "formik";
import * as Yup from "yup";
import CampaignRemoveModal from "./CampaignRemoveModal";
import {
  getCampaigns,
  createCampaign,
  updateCampaign,
  removeCampaign,
} from "../../slices/Campaigns/thunk";

import { useDispatch } from "react-redux";
import { useSelector } from "react-redux";
import { ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import { getGateway } from "../../slices/Gateway/thunk";
import Loader from "../../Components/Common/Loader";

const Campaigns = () => {
  const [modal_list, setmodal_list] = useState(false);

  const [modal_delete, setmodal_delete] = useState(false);

  const [loading, setLoading] = useState(false);

  const [isEditingCampaign, setIsEditingCampaign] = useState(false);

  const [listCampaignId, setListCampaignId] = useState(null);

  const [welcomeMessageAudio, setWelcomeMessageAudio] = useState("");

  const [invalidMessageAudio, setInvalidMessageAudio] = useState(null);

  const [timeOutMessageAudio, setTimeOutMessageAudio] = useState(null);

  const [selectSingleWelcomeTextOrAudio, setSelectSingleWelcomeTextOrAudio] =
    useState(null);

  const [selectSingleInvalidTextOrAudio, setSelectSingleInvalidTextOrAudio] =
    useState(null);

  const [selectSingleTimeOutTextOrAudio, setSelectSingleTimeOutTextOrAudio] =
    useState(null);

  const [selectedSingleGateway, setSelectedSingleGateway] = useState(null);

  const dispatch = useDispatch();

  const { campaigns, alreadyRegisteredError } = useSelector(
    (state) => state.Campaigns
  );
  const { gateways } = useSelector((state) => state.Gateways);

  function tog_list() {
    setmodal_list(!modal_list);
  }

  function tog_delete() {
    setmodal_delete(!modal_delete);
  }

  useEffect(() => {
    if (alreadyRegisteredError) {
      setmodal_list(!modal_list);
    }
  }, [alreadyRegisteredError]);

  useEffect(() => {
    setLoading(true);
    dispatch(getCampaigns()).finally(() => {
      setLoading(false);
    });
    dispatch(getGateway());
  }, [dispatch]);

  const welcomeMessageTextOrAudioOptions = [
    { label: "Text", value: "Text" },
    { label: "Audio", value: "Audio" },
  ];

  function handleSelectSingleWelcomeMessageTextOrAudio(welcomeMessageType) {
    setSelectSingleWelcomeTextOrAudio(welcomeMessageType);
    // if (welcomeMessageType?.value === "Audio") {
    //   validation.setFieldValue("welcomeMessageText", "");
    // }
  }
  const invalidMessageTextOrAudioOptions = [
    { label: "Text", value: "Text" },
    { label: "Audio", value: "Audio" },
  ];

  function handleSelectSingleInvalidMessageTextOrAudio(invalidMessageType) {
    setSelectSingleInvalidTextOrAudio(invalidMessageType);
  }
  const timeOutMessageTextOrAudioOptions = [
    { label: "Text", value: "Text" },
    { label: "Audio", value: "Audio" },
  ];

  function handleSelectSingleTimeOutMessageTextOrAudio(timeOutMessageType) {
    setSelectSingleTimeOutTextOrAudio(timeOutMessageType);
  }

  const gatewayOptions = gateways?.map((gateway) => {
    return {
      id: gateway.id,
      value: gateway.gatewayIpAddress,
      label: gateway.gatewayIpAddress,
    };
  });

  function handleSelectSingleGateway(gateway) {
    setSelectedSingleGateway(gateway);
  }

  const validation = useFormik({
    initialValues: {
      campaignName: "",
      gatewayId: "",
      welcomeMessageText: "",
      InvalidMessageText: "",
      timeOutMessageText: "",
    },
    validationSchema: Yup.object({
      campaignName: Yup.string().required("Please enter campaign name"),
      gatewayId: Yup.string().required("Gateway is required"),
      welcomeMessageText: Yup.string(),
      invalidMessageText: Yup.string(),
      timeOutMessageText: Yup.string(),
    }),
    onSubmit: (values, { resetForm }) => {
      if (isEditingCampaign) {
        dispatch(
          updateCampaign({
            ...values,
            campaignId: listCampaignId,
            welcomeMessageAudio,
            invalidMessageAudio,
            timeOutMessageAudio,
            gatewayId: selectedSingleGateway.id,
          })
        );
      } else {
        dispatch(
          createCampaign({
            ...values,
            welcomeMessageAudio,
            invalidMessageAudio,
            timeOutMessageAudio,
            gatewayId: selectedSingleGateway.id,
          })
        );
      }

      // if (!isEditingCampaign) {
      //   resetForm();
      // }

      resetForm();

      setSelectedSingleGateway(null);
      setSelectSingleInvalidTextOrAudio(null);
      setSelectSingleTimeOutTextOrAudio(null);
      setSelectSingleWelcomeTextOrAudio(null);

      setmodal_list(false);
    },
  });

  console.log("VALIDATION VALUES ->", validation.values);

  function formHandleSubmit(e) {
    e.preventDefault();
    validation.handleSubmit();

    if (!validation.errors) {
      setmodal_list(false);
    }
    return false;
  }

  function handleEditCampaign(campaignData) {
    setIsEditingCampaign(true);
    setmodal_list(!modal_list);
    setListCampaignId(campaignData.id);

    const selectedGateway = gatewayOptions?.find(
      (gateway) => (gateway.id = campaignData.gatewayId)
    );

    if (campaignData.welcomeMessageText) {
      const selectedOption = welcomeMessageTextOrAudioOptions.find(
        (option) => option.value === "Text"
      );

      setSelectSingleWelcomeTextOrAudio(selectedOption);
    } else {
      validation.setFieldValue("welcomeMessageText", ""); // Ensure welcomeMessageText is cleared
    }

    if (campaignData.invalidMessageText) {
      const selectedOption = invalidMessageTextOrAudioOptions.find(
        (option) => option.value === "Text"
      );

      setSelectSingleInvalidTextOrAudio(selectedOption);
    }
    if (campaignData.timeOutMessageText) {
      const selectedOption = timeOutMessageTextOrAudioOptions.find(
        (option) => option.value === "Text"
      );

      setSelectSingleTimeOutTextOrAudio(selectedOption);
    }

    setSelectedSingleGateway(selectedGateway);

    validation.setValues({
      campaignName: campaignData.campaignName,
      welcomeMessageText: campaignData.welcomeMessageText,
      invalidMessageText: campaignData.invalidMessageText,
      timeOutMessageText: campaignData.timeOutMessageText,
      gatewayId: campaignData.gatewayId,
    });
  }

  function tog_list() {
    validation.resetForm();
    setSelectedSingleGateway(null);
    setSelectSingleInvalidTextOrAudio(null);
    setSelectSingleTimeOutTextOrAudio(null);
    setSelectSingleWelcomeTextOrAudio(null);

    setmodal_list(!modal_list);
  }

  document.title = "Campaigns";
  return (
    <React.Fragment>
      <div className="page-content">
        <Container fluid>
          <BreadCrumb title="Campaigns" pageTitle="Management" />
          <Row>
            <Col lg={12}>
              <Card>
                <CardHeader>
                  <h4 className="card-title mb-0">Create a Campaign</h4>
                </CardHeader>

                <CardBody>
                  <div className="listjs-table" id="userList">
                    <Row className="g-4 mb-3">
                      <Col className="col-sm-auto w-100 d-flex justify-content-between">
                        <Button
                          color="primary"
                          className="add-btn me-1"
                          onClick={tog_list}
                          id="create-btn"
                        >
                          <i className="ri-add-line align-bottom me-1"></i> Add
                          Campaign
                        </Button>
                      </Col>
                    </Row>

                    <div className="table-responsive table-card mt-3 mb-1">
                      <table
                        className="table align-middle table-nowrap"
                        id="userTable"
                      >
                        <thead className="table-light">
                          <tr>
                            <th>S.No</th>
                            <th>Campaign Name</th>
                            <th>Welcome Text</th>
                            <th>Invalid Text</th>
                            <th>TimeOut Text</th>

                            <th>Action</th>
                          </tr>
                        </thead>
                        <tbody className="list form-check-all">
                          {loading ? (
                            <tr>
                              <td
                                colSpan={7}
                                style={{
                                  border: "none",
                                  textAlign: "center",
                                  verticalAlign: "middle",
                                }}
                              >
                                <Loader />
                              </td>
                            </tr>
                          ) : (
                            <>
                              {campaigns?.map((campaign, idx) => (
                                <tr key={campaign.id}>
                                  <td>{idx + 1}</td>
                                  <td>{campaign.campaignName}</td>
                                  <td>{campaign.welcomeMessageText}</td>
                                  <td>{campaign.invalidMessageText}</td>
                                  <td>{campaign.timeOutMessageText}</td>

                                  <td>
                                    <div className="d-flex gap-2">
                                      <div className="edit">
                                        <button
                                          className="btn btn-sm btn-primary edit-item-btn"
                                          data-bs-toggle="modal"
                                          data-bs-target="#showModal"
                                          onClick={() => {
                                            handleEditCampaign(campaign);
                                          }}
                                        >
                                          Edit
                                        </button>
                                      </div>

                                      <div className="remove">
                                        <button
                                          className="btn btn-sm btn-danger edit-item-btn"
                                          data-bs-toggle="modal"
                                          data-bs-target="#showModal"
                                          onClick={() => {
                                            setListCampaignId(campaign.id);
                                            tog_delete();
                                          }}
                                        >
                                          Remove
                                        </button>
                                      </div>
                                    </div>
                                  </td>
                                </tr>
                              ))}
                            </>
                          )}
                        </tbody>
                      </table>
                    </div>

                    <div className="d-flex justify-content-end">
                      <div className="pagination-wrap hstack gap-2">
                        <Link
                          className="page-item pagination-prev disabled"
                          to="#"
                        >
                          Previous
                        </Link>
                        <ul className="pagination listjs-pagination mb-0"></ul>
                        <Link className="page-item pagination-next" to="#">
                          Next
                        </Link>
                      </div>
                    </div>
                  </div>
                </CardBody>
              </Card>
            </Col>
          </Row>
        </Container>
      </div>
      <ToastContainer />

      <AddCampaignModal
        validation={validation}
        isEditingCampaign={isEditingCampaign}
        modal_list={modal_list}
        tog_list={tog_list}
        formHandleSubmit={formHandleSubmit}
        alreadyRegisteredError={alreadyRegisteredError}
        welcomeMessageAudio={welcomeMessageAudio}
        setWelcomeMessageAudio={setWelcomeMessageAudio}
        invalidMessageAudio={invalidMessageAudio}
        setInvalidMessageAudio={setInvalidMessageAudio}
        timeOutMessageAudio={timeOutMessageAudio}
        setTimeOutMessageAudio={setTimeOutMessageAudio}
        welcomeMessageTextOrAudioOptions={welcomeMessageTextOrAudioOptions}
        selectSingleWelcomeTextOrAudio={selectSingleWelcomeTextOrAudio}
        handleSelectSingleWelcomeMessageTextOrAudio={
          handleSelectSingleWelcomeMessageTextOrAudio
        }
        invalidMessageTextOrAudioOptions={invalidMessageTextOrAudioOptions}
        selectSingleInvalidTextOrAudio={selectSingleInvalidTextOrAudio}
        handleSelectSingleInvalidMessageTextOrAudio={
          handleSelectSingleInvalidMessageTextOrAudio
        }
        selectSingleTimeOutTextOrAudio={selectSingleTimeOutTextOrAudio}
        timeOutMessageTextOrAudioOptions={timeOutMessageTextOrAudioOptions}
        handleSelectSingleTimeOutMessageTextOrAudio={
          handleSelectSingleTimeOutMessageTextOrAudio
        }
        gatewayOptions={gatewayOptions}
        handleSelectSingleGateway={handleSelectSingleGateway}
        selectedSingleGateway={selectedSingleGateway}
      />

      <CampaignRemoveModal
        modal_delete={modal_delete}
        setmodal_delete={setmodal_delete}
        tog_delete={tog_delete}
        handleDeleteCampaign={() => {
          dispatch(removeCampaign(listCampaignId));
          setmodal_delete(false);
        }}
      />
    </React.Fragment>
  );
};

export default Campaigns;

AddCampaignModal.js

import {
  Alert,
  Input,
  Label,
  Form,
  FormFeedback,
  Modal,
  ModalBody,
  ModalHeader,
  Row,
  Col,
} from "reactstrap";
import "react-toastify/dist/ReactToastify.css";
import Select from "react-select";

function AddCampaignModal({
  modal_list,
  tog_list,
  formHandleSubmit,
  validation,
  isEditingCampaign,
  alreadyRegisteredError,
  welcomeMessageAudio,
  setWelcomeMessageAudio,
  invalidMessageAudio,
  setInvalidMessageAudio,
  timeOutMessageAudio,
  setTimeOutMessageAudio,
  welcomeMessageTextOrAudioOptions,
  selectSingleWelcomeTextOrAudio,
  handleSelectSingleWelcomeMessageTextOrAudio,
  invalidMessageTextOrAudioOptions,
  selectSingleInvalidTextOrAudio,
  handleSelectSingleInvalidMessageTextOrAudio,
  selectSingleTimeOutTextOrAudio,
  timeOutMessageTextOrAudioOptions,
  handleSelectSingleTimeOutMessageTextOrAudio,
  selectedSingleGateway,
  handleSelectSingleGateway,
  gatewayOptions,
}) {
  return (
    <Modal
      isOpen={modal_list}
      toggle={() => {
        tog_list();
      }}
      centered
      className="modal-lg"
    >
      <ModalHeader
        className="bg-light p-3"
        toggle={() => {
          tog_list();
        }}
      >
        {isEditingCampaign ? "Update Campaign" : "Add Campaign"}
      </ModalHeader>
      <Form className="tablelist-form" onSubmit={(e) => formHandleSubmit(e)}>
        <ModalBody style={{ paddingTop: "0px" }}>
          {alreadyRegisteredError && (
            <Alert color="danger" style={{ marginBlock: "10px" }}>
              {alreadyRegisteredError}
            </Alert>
          )}

          <Row>
            <Col md={6}>
              <div className="mb-2">
                <Label htmlFor="campaignName" className="form-label">
                  Campaign Name
                </Label>

                <Input
                  id="campaignName"
                  name="campaignName"
                  className="form-control"
                  placeholder="Enter Campaign Name"
                  type="text"
                  onChange={validation.handleChange}
                  onBlur={validation.handleBlur}
                  value={validation.values.campaignName || ""}
                  invalid={
                    validation.touched.campaignName &&
                    validation.errors.campaignName
                      ? true
                      : false
                  }
                />

                {validation.touched.campaignName &&
                validation.errors.campaignName ? (
                  <FormFeedback type="invalid">
                    {validation.errors.campaignName}
                  </FormFeedback>
                ) : null}
              </div>
            </Col>

            <Col md={6}>
              <div className="mb-2">
                <Label htmlFor="gatewayId" className="form-label">
                  Gateways
                </Label>

                <Select
                  id="gatewayId"
                  name="gatewayId"
                  value={selectedSingleGateway}
                  onChange={(gateway) => {
                    handleSelectSingleGateway(gateway);
                    validation.setFieldValue("gatewayId", gateway.id);
                  }}
                  gateway
                  options={gatewayOptions}
                  placeholder="Select Gateway"
                  styles={{
                    control: (provided, state) => ({
                      ...provided,
                      borderColor: state.isFocused ? "#a8d9f3" : "#ced4da",
                      "&:hover": {
                        borderColor: "#ced4da",
                      },
                    }),
                  }}
                />
              </div>
            </Col>

            <Col md={6}>
              <div className="mb-2">
                <Label
                  htmlFor="welcomeMessageTextOrAudioSelect"
                  className="form-label"
                >
                  Welcome Message Type
                </Label>

                <Select
                  id="welcomeMessageTextOrAudioSelect"
                  name="welcomeMessageTextOrAudioSelect"
                  value={selectSingleWelcomeTextOrAudio}
                  onChange={(messageOrAudio) => {
                    handleSelectSingleWelcomeMessageTextOrAudio(messageOrAudio);
                  }}
                  options={welcomeMessageTextOrAudioOptions}
                  placeholder="Select Welcome Message Type"
                  styles={{
                    control: (provided, state) => ({
                      ...provided,
                      borderColor: state.isFocused ? "#a8d9f3" : "#ced4da",
                      "&:hover": {
                        borderColor: "#ced4da",
                      },
                    }),
                  }}
                />
              </div>
            </Col>

            {selectSingleWelcomeTextOrAudio?.value === "Text" ? (
              <Col md={6}>
                <div className="mb-2">
                  <Label htmlFor="welcomeMessageText" className="form-label">
                    Welcome Message Text
                  </Label>

                  <Input
                    id="welcomeMessageText"
                    name="welcomeMessageText"
                    className="form-control"
                    placeholder="Enter Welcome Text"
                    type="text"
                    onChange={validation.handleChange}
                    onBlur={validation.handleBlur}
                    value={validation.values.welcomeMessageText}
                    invalid={
                      validation.touched.welcomeMessageText &&
                      validation.errors.welcomeMessageText
                        ? true
                        : false
                    }
                  />

                  {validation.touched.welcomeMessageText &&
                  validation.errors.welcomeMessageText ? (
                    <FormFeedback type="invalid">
                      {validation.errors.welcomeMessageText}
                    </FormFeedback>
                  ) : null}
                </div>
              </Col>
            ) : selectSingleWelcomeTextOrAudio?.value === "Audio" ? (
              <Col lg={6}>
                <div>
                  <Label htmlFor="formFile" className="form-label">
                    Welcome Message Audio
                  </Label>
                  <Input
                    id="welcomeMessageAudio"
                    name="welcomeMessageAudio"
                    className="form-control"
                    type="file"
                    onChange={(e) => setWelcomeMessageAudio(e.target.files[0])}
                  />
                </div>
              </Col>
            ) : (
              <Col lg={6}></Col>
            )}

            <Col md={6}>
              <div className="mb-2">
                <Label htmlFor="invalidMessageText" className="form-label">
                  Invalid Message Type
                </Label>

                <Select
                  id="invalidMessageTextOrAudioSelect"
                  name="invalidMessageTextOrAudioSelect"
                  value={selectSingleInvalidTextOrAudio}
                  onChange={(messageOrAudio) => {
                    handleSelectSingleInvalidMessageTextOrAudio(messageOrAudio);
                  }}
                  options={invalidMessageTextOrAudioOptions}
                  placeholder="Select Welcome Message Type"
                  styles={{
                    control: (provided, state) => ({
                      ...provided,
                      borderColor: state.isFocused ? "#a8d9f3" : "#ced4da",
                      "&:hover": {
                        borderColor: "#ced4da",
                      },
                    }),
                  }}
                />
              </div>
            </Col>

            {selectSingleInvalidTextOrAudio?.value === "Text" ? (
              <Col md={6}>
                <div className="mb-2">
                  <Label htmlFor="welcomeMessageText" className="form-label">
                    Invalid Message Text
                  </Label>

                  <Input
                    id="invalidMessageText"
                    name="invalidMessageText"
                    className="form-control"
                    placeholder="Enter Invalid Text"
                    type="text"
                    onChange={validation.handleChange}
                    onBlur={validation.handleBlur}
                    value={validation.values.invalidMessageText || ""}
                    invalid={
                      validation.touched.invalidMessageText &&
                      validation.errors.invalidMessageText
                        ? true
                        : false
                    }
                  />

                  {validation.touched.invalidMessageText &&
                  validation.errors.invalidMessageText ? (
                    <FormFeedback type="invalid">
                      {validation.errors.invalidMessageText}
                    </FormFeedback>
                  ) : null}
                </div>
              </Col>
            ) : selectSingleInvalidTextOrAudio?.value === "Audio" ? (
              <Col lg={6}>
                <div>
                  <Label htmlFor="formFile" className="form-label">
                    Invalid Message Audio
                  </Label>
                  <Input
                    id="invalidMessageAudio"
                    name="invalidMessageAudio"
                    className="form-control"
                    type="file"
                    onChange={(e) => setInvalidMessageAudio(e.target.files[0])}
                  />
                </div>
              </Col>
            ) : (
              <Col lg={6}></Col>
            )}

            <Col md={6}>
              <div className="mb-2">
                <Label
                  htmlFor="timeOutMessageTextOrAudioSelect"
                  className="form-label"
                >
                  TimeOut Message Type
                </Label>

                <Select
                  id="timeOutMessageTextOrAudioSelect"
                  name="timeOutMessageTextOrAudioSelect"
                  value={selectSingleTimeOutTextOrAudio}
                  onChange={(messageOrAudio) => {
                    handleSelectSingleTimeOutMessageTextOrAudio(messageOrAudio);
                  }}
                  options={timeOutMessageTextOrAudioOptions}
                  placeholder="Select Time Out Message Type"
                  styles={{
                    control: (provided, state) => ({
                      ...provided,
                      borderColor: state.isFocused ? "#a8d9f3" : "#ced4da",
                      "&:hover": {
                        borderColor: "#ced4da",
                      },
                    }),
                  }}
                />
              </div>
            </Col>

            {selectSingleTimeOutTextOrAudio?.value === "Text" ? (
              <Col md={6}>
                <div className="mb-2">
                  <Label htmlFor="timeOutMessageText" className="form-label">
                    TimeOut Message Text
                  </Label>

                  <Input
                    id="timeOutMessageText"
                    name="timeOutMessageText"
                    className="form-control"
                    placeholder="Enter TimeOut Text"
                    type="text"
                    onChange={validation.handleChange}
                    onBlur={validation.handleBlur}
                    value={validation.values.timeOutMessageText || ""}
                    invalid={
                      validation.touched.timeOutMessageText &&
                      validation.errors.timeOutMessageText
                        ? true
                        : false
                    }
                  />
                </div>
              </Col>
            ) : selectSingleTimeOutTextOrAudio?.value === "Audio" ? (
              <Col lg={6}>
                <div>
                  <Label htmlFor="formFile" className="form-label">
                    TimeOut Message Audio
                  </Label>
                  <Input
                    id="timeOutMessageAudio"
                    name="timeOutMessageAudio"
                    className="form-control"
                    type="file"
                    onChange={(e) => setTimeOutMessageAudio(e.target.files[0])}
                  />
                </div>
              </Col>
            ) : (
              <Col lg={6}></Col>
            )}
          </Row>

          <div className="text-end">
            <button type="submit" className="btn btn-primary">
              {isEditingCampaign ? "Update Campaign" : "Save Campaign"}
            </button>
          </div>
        </ModalBody>
      </Form>
    </Modal>
  );
}

export default AddCampaignModal;

Discard millisecond part from timestamp when defining schema with @dsnp/parquetjs library

I want to define a parquet schema using @dsnp/parquetjs library.

One of the fields of the Schema needs to be in Timestamp without milliseconds (Unix timestamp for instance).

The only available timestamp types in this library are TIMESTAMP_MILLIS and TIMESTAMP_MICROS.

Do you have some workaround solutions?

Here is my code so far

export const mySchema = new ParquetSchema({
  creationDate: {
    type: 'TIMESTAMP_MILLIS', // I need it without milliseconds part
    optional: true,
  },
  // ... other fields
});

How to display conditional inputs of radio buttons without removing generate buttons at the bottom

I’m building a program for work that assists in generating a medical SITREP report for our own purposes, and I’m having a bit of trouble with the HTML/jscript side of things. With help from ChatGPT, I was able to get the ball rolling a bit, but I’ve run into an issue…

The base of the HTML doc is a form with a series of labels and inputs for information that’s compiled in the function generateReport(). That section I plan to work on later; however, at the moment it’s part of the GUI that I’m trying to debug.

At the base of the code before the Generate Report and Copy SITREP buttons are a series of three radio buttons. I had it working once before, but the radio buttons were supposed to display different labels and inputs based on which radio button was selected. However, now for some reason, no matter which radio button is clicked, it doesn’t show any conditional inputs, and in fact it removes the Generate Report and Copy SITREP buttons entirely!

Like I said before, I attempted to use ChatGPT to assist me in debugging and fixing this issue, but it may have just made it worse in the process. Regardless, here’s the code I currently have. If you all are able to assist me with this issue, I’ll be extremely grateful! 🙂

function checkSymptoms() {
  var symptoms = document.getElementById("symptoms").value;
  var symptomsDetails = document.getElementById("symptomsDetails");
  if (symptoms === "smallCut" || symptoms === "jammed" || symptoms === "sprain" || symptoms === "eyeDamage" || symptoms === "other") {
    symptomsDetails.style.display = "inline-block";
  } else {
    symptomsDetails.style.display = "none";
  }
}

function showFields() {
  // Hide all conditional inputs initially
  document.getElementById('stayingWork').classList.add('hidden');
  document.getElementById('goingHome').classList.add('hidden');
  document.getElementById('emsResponse').classList.add('hidden');

  // Get the selected option
  const selectedOption = document.querySelector('input[name="response"]:checked')?.value;

  // Show fields based on selected option
  if (selectedOption === 'stayingWork') {
    document.getElementById('stayingWork').classList.remove('hidden');
  } else if (selectedOption === 'goingHome') {
    document.getElementById('goingHome').classList.remove('hidden');
  } else if (selectedOption === 'emsResponse') {
    document.getElementById('emsResponse').classList.remove('hidden');
  } else {
    document.getElementById('sitrepSection').classList.add('hidden');
  }
}

function generateReport() {
  var time1 = document.getElementById("time1").value;
  var timeZone = document.getElementById("timeZone").value;
  var employeeType1 = document.getElementById("employeeType1").value;
  var employee1 = document.getElementById("employee1").value;
  var employeeId1 = document.getElementById("employeeId1").value;
  var employeeType2 = document.getElementById("employeeType2").value;
  var employee2 = document.getElementById("employee2").value;
  var employeeId2 = document.getElementById("employeeId2").value;
  var symptoms = document.getElementById("symptoms").value;
  var symptomsDetails = document.getElementById("symptomsDetails").value;

  // Object mapping symptoms to sentence structures
  var symptomSentences = {
    "dizzy": "who was feeling dizzy while on shift",
    "nausea": "who began feeling nauseous while on shift",
    "vomit": "who had begun vommiting while on shift",
    "sweats": "who had started sweating heavily on shift",
    "smallCut": "who had sustained a small cut on their {details}",
    "eyeDamage": "who had sustained eye damage due to {details}",
    "jammed": "who had jammed their {details}",
    "breathing": "who was having trouble breathing",
    "tremors": "who was experiencing shakes and tremors in their {details}",
    "headInjury": "who had sustained a head injury while on shift",
    "slip": "who had experienced a slip and fall event",
    "sprain": "who had sprained their {details} while on shift",
    "chestPain": "who was experiencing chest pains",
    "severeHeadache": "who begun experiencing a severe headache",
    "labor": "who had begun experience symptoms of labor",
    "pregnancy complication": "who had possibly begun experiencing a pregnancy complication",
    "seizure": "who had experienced a seizure while on shift",
    "heartAttack": "who had begun showing symptoms of a heart attack",
    "feinting": "who had feinted while on shift",
    "panicAttack": "who began having a panic attack while on shift",
    "other": "who was experiencing {details}"
  };

  // If the symptom requires details (e.g., sprain location), we add it
  var sentence = symptomSentences[symptoms];
  if (symptoms === "smallCut" || symptoms === "eyeDamage" || symptoms === "jammed" || symptoms === "tremors" || symptoms === "sprain" || symptoms === "other") {
    if (symptomsDetails) {
      sentence = sentence.replace("{details}", symptomDetails);
    } else {
      sentence = sentence.replace("{details}", "unspecified area");
    }
  }
  var mod = document.getElementById("mod").value;
  var location = document.getElementById("location").value;
  var time2 = document.getElementById("time2").value;
  var ERTMember = document.getElementById("ERTMember").value;
  var ERTResponse = document.getElementById("ERTResponse").value;

  var report = "At " + time1 + " " + timeZone + ", the RSOC (Regional Security Operations Center) received a call from " +
    employeeType1 + " employee " + employee1 + " (" + employeeId1 + ") regarding " + employeeType2 + " employee " + employee2 + " (" + employeeId2 + ") " +
    sentence + " in Mod " + mod + " nearby column " + location + ". The ERT Team was contacted through the Push To Talk (PTT) phone at " + time2 + " " + timeZone +
    ", and ERT Team member " + ERTMember + " responded stating that they were en route. ERT arrived at the patient at " + ERTResponse + " " + timeZone +
    " and began assessing the situation. ";

  document.getElementById("sitrepReport").textContent = report;
  alert("SITREP Generated!");
}

function copyToClipboard() {
  var reportText = document.getElementById("sitrepReport").textContent;
  navigator.clipboard.writeText(reportText).then(function() {
    alert('SITREP Report copied to clipboard');
  }, function(err) {
    alert('Error in copying text: ', err);
  });
}
body {
  font-family: Arial, sans-serif;
  background-color: #f4f4f4;
  margin: 0;
  padding: 20px;
}

h1 {
  color: #333;
}

form {
  background-color: #fff;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  max-width: 900px;
  margin: auto;
}

.form-group {
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  box-sizing: border-box;
}

.form-group label {
  flex: 0 0 auto;
  margin-right: 10px;
  font-weight: bold;
}

.form-group input[type="text"],
.form-group select {
  flex: 1;
  margin: 0;
  margin-right: 10px;
  box-sizing: border-box;
}

.form-group input[type="button"] {
  background-color: #4CAF50;
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 16px;
}

.form-group input[type="button"]:hover {
  background-color: #45a049;
}

.radio-group {
  margin-bottom: 10px;
}

.radio-group label {
  margin-right: 20px;
}

.conditional-inputs {
  display: none;
  margin-top: 10px;
}

.conditional-inputs input[type="text"] {
  width: 100%;
  max-width: 500px;
  margin: 5px 0;
  box-sizing: border-box;
}

pre {
  background-color: #fff;
  padding: 10px;
  border-radius: 4px;
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
  max-width: 800px;
  margin: auto;
}

#copyButton {
  background-color: #008CBA;
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 16px;
  margin-top: 10px;
}

#copyButton:hover {
  background-color: #007bb5;
}

.hidden {
  display: none;
}
<h1>Medical SITREP Report Generator</h1>
<form id="incidentForm">
  <div class="form-group">
    <label for="time1">Initial Call Time:</label>
    <input type="time" id="time1" name="time1" required>
    <label for="timeZone">Time Zone:</label>
    <select id="timeZone" name="timeZone" required>
      <option value="">Select Time Zone</option>
      <option value="CST">CST</option>
      <option value="EST">EST</option>
      <option value="PST">PST</option>
    </select>
  </div>
  <div class="form-group">
    <label for="employeeType1">Company:</label>
    <select id="employeeType1" name="employeeType1" required>
      <option value="">--Select Company--</option>
      <option value="Flex">Flex</option>
      <option value="Aramark">Aramark</option>
      <option value="SolarEdge">SolarEdge</option>
      <option value="Aerotek">Aerotek</option>
      <option value="Hallmark">Hallmark</option>
      <option value="VOLT">VOLT</option>
      <option value="Staffmark">Staffmark</option>
      <option value="ONIN">ONIN</option>
      <option value="Allied Universal">Allied Universal</option>
      <option value="Facilities">Facilities</option>
      <option value="Other">Other</option>
    </select><br>
    <label for="employee1">Reporting Employee:</label>
    <input type="text" id="employee1" name="employee1" required>
    <label for="employeeId1">ID Number:</label>
    <input type="text" id="employeeId1" name="employeeId1" required>
  </div>
  <div class="form-group">
    <label for="employeeType2">Company:</label>
    <select id="employeeType2" name="employeeType2" required>
      <option value="">--Select Company--</option>
      <option value="Flex">Flex</option>
      <option value="Aramark">Aramark</option>
      <option value="SolarEdge">SolarEdge</option>
      <option value="Aerotek">Aerotek</option>
      <option value="Hallmark">Hallmark</option>
      <option value="VOLT">VOLT</option>
      <option value="Staffmark">Staffmark</option>
      <option value="ONIN">ONIN</option>
      <option value="Allied Universal">Allied Universal</option>
      <option value="Facilities">Facilities</option>
      <option value="Other">Other</option>
    </select>
    <label for="employee2">Patient Name:</label>
    <input type="text" id="employee2" name="employee2" required>
    <label for="employeeId2">Patient ID Number:</label>
    <input type="text" id="employeeId2" name="employeeId2" required>
  </div>
  <div class="form-group">
    <label for="symptoms">Symptoms:</label>
    <select id="symptoms" name="symptoms" onchange="checkSymptoms()" required>
      <option value="">--Select Symptoms--</option>
      <option value="dizzy">Dizziness</option>
      <option value="nausea">Nausea</option>
      <option value="vommit">Vommiting</option>
      <option value="sweats">Sweating</option>
      <option value="smallCut">Small Cut</option>
      <option value="eyeDamage">Something in their eye</option>
      <option value="jammed">Jammed Body Part</option>
      <option value="breathing">Difficulty Breathing</option>
      <option value="tremors">Tremors and/or Shakes</option>
      <option value="headInjury">Head injury</option>
      <option value="slip">Slip and Fall</option>
      <option value="sprain">Sprain</option>
      <option value="chestPain">Chest Pain</option>
      <option value="severeHeadache">Severe Headache</option>
      <option value="labor">Labor</option>
      <option value="pregnancy complication">Pregnancy Complication</option>
      <option value="seizure">Seizure</option>
      <option value="heartAttack">Heart Attack Symptoms</option>
      <option value="feinting">Feinting</option>
      <option value="panicAttack">Anxiety/Panic Attack</option>
      <option value="other">Other</option>
    </select>
    <input type="text" id="symptomsDetails" name="symptomsDetails" placeholder="Provide more details" style="display:none; margin-left: 10px;">
  </div>
  <div class="form-group">
    <label for="mod">Mod:</label>
    <select id="mod" name="mod" required>
      <option value="">--Select Mod--</option>
      <option value="A">A</option>
      <option value="B">B</option>
      <option value="C">C</option>
      <option value="D">D</option>
      <option value="E">E</option>
      <option value="F">F</option>
      <option value="G">G</option>
      <option value="H">H</option>
      <option value="I">I</option>
      <option value="J">J</option>
      <option value="K">K</option>
      <option value="L">L</option>
      <option value="M">M</option>
      <option value="N">N</option>
      <option value="O">O</option>
      <option value="P">P</option>
      <option value="Q">Q</option>
      <option value="R">R</option>
      <option value="S">S</option>
      <option value="T">T</option>
      <option value="U">U</option>
      <option value="V">V</option>
      <option value="W">W</option>
    </select>
    <label for="location">Exact Location:</label>
    <input type="text" id="location" name="location" required>
  </div>
  <div class="form-group">
    <label for="time2">Time ERT Team Contacted:</label>
    <input type="time" id="time2" name="time2" required style="width: 150px;">
  </div>
  <div class="form-group">
    <label for="ERTMember">Responding ERT Member:</label>
    <input type="text" id="ERTMember" name="ERTMember" required>
  </div>
  <div class="form-group">
    <label for="ERTResponse">Time ERT Arrived:</label>
    <input type="time" id="ERTResponse" name="ERTResponse" required>
  </div>
  <div class="radio-group">
    <label><input type="radio" name="response" value="stayingWork" onclick="showFields()"> Staying at Work</label>
    <label><input type="radio" name="response" value="goingHome" onclick="showFields()"> Going Home</label>
    <label><input type="radio" name="response" value="emsResponse" onclick="showFields()"> EMS Responded</label>
  </div>
  <div id="stayingWork" class="hidden">
    <label for="allClearTime">Time of All Clear:</label>
    <input type="time" id="allClearTime" name="allClearTime" </div>
    <div id="goingHome" class="hidden">
      <label for="leftSite">Left site at:</label>
      <input type="time" id="leftSite" name="leftSite"><br>
      <label for="homeAllClearTime">Time of All Clear:</label>
      <input type="time" id="homeAllClearTime" name="homeAllClearTime">
    </div>
    <div id="emsResponse" class="hidden">
      <label for="unitNumber">Unit #:</label>
      <input type="text" id="unitNumber" name="unitNumber"><br>
      <label for="arrivedSite">Arrived at Site:</label>
      <input type="time" id="arrivedSite" name="arrivedSite"><br>
      <label for="arrivedPatient">Arrived at Patient:</label>
      <input type="time" id="arrivedPatient" name="arrivedPatient"><br>
      <label for="hospitalName">Hospital Name:</label>
      <input type="text" id="hospitalName" name="hospitalName"><br>
      <label for="leftSiteEMS">Left site at:</label>
      <input type="time" id="leftSiteEMS" name="leftSiteEMS"><br>
      <label for="emsAllClearTime">Time of All Clear:</label>
      <input type="time" id="emsAllClearTime" name="emsAllClearTime">
    </div>
    <div class="form-group">
      <h2>SITREP Report:</h2>
      <pre id="sitrepReport:"></pre>
      <button type="button" onclick="generateReport()">Generate SITREP</button>
      <button type="button" onclick="copyToClipboard()">Copy SITREP</button>
    </div>
</form>

How can I create a simple heatmap with only javascript? [closed]

Im trying to create a 2 dimensional heatmap with only javascript using react. Im really lost as how to possibly do it. Appologies for the code, but this is where Im at, not understanding how I can do it. Would be very helpful of some tips on how to approach this.

const data = [
    {y: "jan", y: 2020, value: "bad"},
    {y: "feb", y: 2020, value: "good"},
    {y: "mar", y: 2020, value: "bad"},
    {y: "apr", y: 2020, value: "bad"},
    {y: "jan", y: 2021, value: "bad"},
    {y: "feb", y: 2021, value: "good"},
    {y: "mar", y: 2021, value: "bad"},
    {y: "apr", y: 2021, value: "good"},
    {y: "may", y: 2021, value: "good"},
    {y: "mar", y: 2022, value: "bad"},
    {y: "apr", y: 2023, value: "bad"},
];

const xAxis = ["jan", "feb", "mar", "apr", "may"];
const yAxis = data.map(item => item.y);

const App = () => {
    return (
        <div>
            {months.map(month => {
                return years.map(year=> {
                    return <div><h1>year</h1></div>
                })
            })}
        </div>
    )
}

The map Im trying to create:
enter image description here

Google Analytics from a third party script

I am developing a widget that can be added to a host website via snippet of js code that once rendered will add an iframe to the host website.

Now my customers want to give me their GA tracking id so that I can send events from my widget to their GA4 account.

How should I handle this ?

  1. Add GA4 tag to the widget code and send the events from within the iframe, regardless of any GA4 tag that the host / parent page has
  2. Post messages from within the iframe page to the parent window and then intercept them on parent window and send them to GA4 from there. I will have to check if the parent window already has GA4 tag and if so, use it. If not, I will have to add the tag to the parent window.

Couple of things to note:

  1. My customer has added my widget code into their website so I can do dom manipulation on their site.
  2. My widget iframe is running on my domain which is different from my customer’s parent window domain

React – pass returned value to different component

I’m trying to be able to load a product in a separate child component (which is enabled when a user clicks a product from a product list rendered map on the parent component).

I’ve set up a function to .filter through the list of products so just the product at the index value (that matches the ID of the product clicked from the product list) and return it in a variable.

In Parent Component

let focussedProduct = "";

const viewProduct = (productID) => {
  focussedProduct = focusProduct.filter((e, index, array)=>{
    return index == productID
  })
  console.log(focussedProduct[0]);
};
<div className='product' key={product.id} onClick={() => viewProduct(product.id)}>

Which console logs this, so it’s returning what I need when clicking random items:

enter image description here

However I’m really struggling to pass the returned value/data to the child component to map it and start rendering that product, I thought it would be as easy as passing the variable like this.

Parent component

<Product 
  focussedProduct = {focussedProduct}
/>

Child component

import React, {useState} from "react";

const Product = (props) => {  
    console.log(props.focussedProduct)  
}

export default Product;    

But it’s not returning anything in the console to use/map. So I’m guessing I’m doing something wrong and I’m sure it’s simple but I’m not getting there even after doing a bit of googling. Help is much appreciated.

Server reconciliation issue with mousemove system

Context

I’m having trouble figuring out exactly how to implement server reconciliation in my game, which uses JavaScript, Node.js, and WebSockets. I’m creating an Agar.io-type game where the player is a circle that controls their movement with their mouse. When the player moves their mouse, it calculates the direction they are moving in and applies that value to the player on each frame.

TL;DR / ESSENTIAL QUESTIONS

My current implementation of server reconciliation is creating a choppiness/jittering effect on the player’s screen, so I’m doing something wrong.

I’m wondering how to fix the disparity between the number of frames the server runs and the number of frames the client runs — the client runs more times than the server, which I track with a variable. This discrepancy seems to be causing issues with reconciliation — how would a loop running at the same rate give different values on the server vs. the client?

Additionally, I’m wondering if there are any overarching ideas on how I can more effectively implement server reconciliation in my game. The examples I’ve seen don’t fit my exact scenario as several factors influence the exact position the player is in at a given time. I’m tracking the number of mouse movements the player makes the how many frames they move in that direction for, and I don’t see any other way to do it, but are there any other ideas? Especially because I’m not sure how to allow the server to be authoritative while allowing client prediction (because of the difference between how many frames run according to the server and according to the player).

Problem

While I understand the concept of server reconciliation, I’m having a tough time implementing it in my game as there are several factors that play into the player’s position at any given moment: their current X/Y positions, speed, direction they are moving in (determined by the mouse’s movements), and their velocity (velocity occurs when the players bump into each other).

When I first tried implementing server reconciliation, I just tracked the user’s mouse movements and made the server process those events. However, I realized that this doesn’t really track the player’s position at all because what matters is how many frames the user runs while going in the specific direction the mouse dictates. So, I decided to count the number of frames that run with each mouse movement on the client side. Here is just the game loop code that runs on each frame and the incrementing of the number of frames:

const fps = 66.67;
const msPerFrame = 1000 / fps;

function gameLoop() {
    window.requestAnimationFrame(gameLoop);

    const msNow = window.performance.now();
    const msPassed = msNow - msPrev;

    if (msPassed < msPerFrame) return; //limit client-side frame rate as different screens can have different rates

    framesWithCurrentDirection++; // add 1 to frames that have run with current direction player is moving in
...

Then, when the mouse moves, it adds the player’s current position information to an array along with the number of frames that ran while the player was moving in that direction:

$(canvas).on('mousemove', (event) => {
    ...
    sequenceNumber++; //keep track of sequence number
    //add all relevant player info to use when server responds with its sequence number
    playerInputs.push({ 
        sequenceNumber: sequenceNumber,
        framesWithCurrentDirection: framesWithCurrentDirection, //tracks # of frames run
        movingDirection: { x: xMovingDirection, y: yMovingDirection}, //calculated with each mouse move
        speedMultiplier: multiplier, //how fast player should go (based on how far mouse is from player)
        vx: localPlayer.vx, //x velocity
        vy: localPlayer.vy, //y velocity
        speed: localPlayer.speed, //player speed
        radius: localPlayer.radius //player radius
    });

    //send the direction the player moves in to the server
    const moveData = {
        playerID: localPlayer.id,
        xMovingDirection: xMovingDirection,
        yMovingDirection: yMovingDirection,
        speedMultiplier: multiplier,
        sequenceNumber: sequenceNumber
    };
    socket.emit('playerMove', moveData);

    framesWithCurrentDirection = 0; //reset frames with current direction
});

On the server, the player’s mouse movements are acknowledged and the server updates the player’s sequence number to track how many mouse move events have been processed (which is stored in the Player class):

socket.on('playerMove', (data) => {
       const sequenceNumber = data.sequenceNumber;
        player.sequenceNumber = sequenceNumber;
        player.framesWithCurrentDirection = 0; //reset # of frames moving in current direction
    });

Additionally, the server has a gameLoop() running at the same FPS (66.67) as the client side, which does several things, including emitting player’s positions to all connected players in a given room and updating the number of frames the game runs while the player is going in the direction their mouse dictates:

const frameRate = 1000 / 66.67;
setInterval(() => {
    rooms.forEach((room, roomId) => {
        gameLoop(room, roomId);
    });
    
}, frameRate);

function gameLoop() {
     ...

    room.players.forEach((player) => {
     player.framesWithCurrentDirection++; //increase frames moving in current direction for each player

    ...

    //emits player positions to all room’s connected players
    const playerPositions = Array.from(room.players.values()).map(player => ({
        playerID: player.id,
        x: player.x,
        y: player.y,
        speed: player.speed,
        sequenceNumber: player.sequenceNumber,
        frames: player.framesWithCurrentDirection
    }));
    io.to(roomId).emit('playerPositionsUpdate', playerPositions);
}

Back on the client side, when ‘playerPositionsUpdate’ is received, it checks the received sequenceNumber against the stored mouse movements input array and splices the sequenceNumber values that are less than what the server provided. It then applies the unfinished mouse movements to move the player from the server’s last processed position to their correct position. The idea is that, for each unprocessed mouse movement, the client checks the number of frames the server gives back against the number of frames it was keeping track of on its own. For each unprocessed frame, it runs the move() method for the player:

socket.on('playerPositionsUpdate', (playerPositions) => {
    playerPositions.forEach(({ playerID, x, y, speed, sequenceNumber, frames }) => {
        //set player’s position to whatever server says
        player.x = x;
        player.y = y;
        player.speed = speed;
            
        //find the index of the last event that the server has processed
        const lastBackendIndex = playerInputs.findIndex(input => input.sequenceNumber === sequenceNumber);
            
        //if the index exists (if something is unprocessed), remove everything up to that point from the playerInputs array, which stores the player’s mousemove info   
        if (lastBackendIndex > -1) {
            playerInputs.splice(0, lastBackendIndex + 1);
        }

        // Apply any unprocessed inputs
        playerInputs.forEach(input => {
            const framesLeft = input.framesWithCurrentDirection - frames;
            const framesStartingPoint = Math.max(0, input.framesWithCurrentDirection - framesLeft);
            //start at the frame that has not been processed yet
            for (let i = framesStartingPoint; i < input.framesWithCurrentDirection; i++) {
                const velocity = { vx: input.vx, vy: input.vy };
                const coordinates = { x: x, y: y };
                player.move(input.movingDirection, input.speedMultiplier, input.speed, velocity, coordinates); //normal player movement method
            }
        });
    } else {
        // For other players, smoothly interpolate to the server position
        gsap.to(player, {
            x: x,
            y: y,
            speed: speed,
            duration: 0.05,
            ease: 'linear'
        });
    });
});



With all of this said, I’m finding that the server gives a lower number of frames than the client does. It seems that the frames need to match up exactly for this to work. For example, after about 2 seconds, the server says that much fewer frames have run than the client says. This is an issue because it makes it difficult to track how many frames have truly run. And it means that extra frames are being processed, leading to choppiness in player movement.

Question

This code is creating choppiness (my game is smooth on my local computer without server reconciliation, but I have to implement it because my live server is a lot slower). Any ideas how to fix this issue with the inconsistency in the frames? Additionally, do you see anything wrong with the way I’m going about server reconciliation? It’s the type of issue where something small could be wrong and fixing that would fix the whole issue, but I’m not sure if that’s the case or if I’m just completely off. Any suggestions?

Re-exporting antd components while keeping /es direcory available

I am using yarn workspaces for my project, with following structure

root
   packages
      app1
          tsconfig.json
      app2
      ui-kit
          ant-design
              index.d.ts
          tsconfig.json
   tsconfig.json

in index.d.ts I am re-exporting antd component wrapped with additional props, but antd has a lot of types in antd/es/* I need to use in my project.
I dont want to re-export all of them (because there is a lot of them and structure might change).

So I modified ui-kit/tsconfig.json to be

{
    "extends": "@my-config-lib/tsconfig.base.json",
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
            "ant-design/es/*": ["node_modules/antd/es/*"]
        },
    },
    "include": ["**/*.ts", "**/*.tsx", "**/*.d.ts"],
    "exclude": ["dist", "node_modules"]
}

While this help me to import from within ui-ki using ./ant-design/es/menu/etc
This does not work when this ui-kit is used in app1 or app2.
I tried setting references in app1/tsconfig.json but that does not seem to help.
Also i have tried adding paths in app1/tsconfig.json to be "@fineapp/ui-kit/antd-design/es*" : "../ui-kit/node_modules/antd/es/*"
but also no luck.

Is there a way to tell app1/tsconfig to look for paths in ui-kit/tsconfig.json while trying import code from it ?

Unable to consume the shared library by HOST in Module Federation

I am working on Module Federation, and I have built One host app and several remote apps.
The thing is I have installed some dependencies at host side and want to share it its remotes, so that the remotes does not need to install these dependencies again.

From my host app webpack.config.js, I’m sharing the dependencies, show below:

shared: {
...deps,
react: {
singleton: true,
requiredVersion: deps.react,
},
"react-dom": {
singleton: true,
requiredVersion: deps["react-dom"],
},
"react-router-dom": {
singleton: true,
requiredVersion: deps["react-router-dom"],
},
"react-redux": {
singleton: true,
requiredVersion: "9.1.2",
},
"@reduxjs/toolkit": {
singleton: true,
requiredVersion: "2.2.7",
},
},

and in the remote apps, I'm consuming it as:
shared: {
react: {
singleton: true,
requiredVersion: deps.react,
},
"react-dom": {
singleton: true,
requiredVersion: deps["react-dom"],
},
"react-router-dom": {
singleton: true,
requiredVersion: false,
},
"react-redux": {
singleton: true,
requiredVersion: false,
},
"@reduxjs/toolkit": {
singleton: true,
requiredVersion: false,
},
},

The thing is whenever I build all the apps, using npm run build command, I get
at host that it shared the libraries:
provide-module modules 210 bytes
provide shared module (default) @reduxjs/[email protected] = ./node_modules/@reduxjs…(truncated) 42 bytes [built] [code generated]

  • 4 modules:

But at while building the remote apps, I get:

consume-shared-module modules 84 bytes
consume shared module (default) react@* (singleton) 42 bytes [built] [code generated]
consume shared module (default) react-redux@* (singleton) 42 bytes [built] [code generated]

ERROR in resolving fallback for shared module react-redux

What I see is, the host is sharing the dependencies and remotes are receiving it, but still on building the remote apps, it is looking for the libraries in inside its node_modules directory

What I see is, the host is sharing the dependencies and remotes are receiving it, but still on building the remote apps, it is looking for the libraries in inside its node_modules directory

How can I create a list in SAPUI5 where each line contains data from multiple entities?

I’m trying to create a page with a questionnaire, where users are presented a list of questions and have to answer them. There are multiple types of answers (multiple choice, textfields, numeric ratings, etc.).

I managed to load the questions correctly from my odata service and the view (including the different answer fields) is rendered correctly. But now I’m struggling to actually bind the answer fields to the data.

I have a relation between the questions and the answers in my database, but since the list is auto-generated using the question items, I don’t know how to correctly associate and fill the fields.

I’ve bound the questions like this to the list:

this.getView().bindElement({
    path: "/Questionnaire(ID=" + sID + ",IsActiveEntity=true)",
    parameters: {
        expand: "questions" // Include the questions association
    },
    events: {
        dataReceived: function (oData) {
            console.log("Data received:", oData);
        },
        dataRequested: function () {
            console.log("Data requested...");
        }
    }
});

I’ve already tried multiple things, but I didn’t even manage to retrieve the data and log it to the console or something like that.
Most things I’ve found when searching for a solution use OData v2 where you could use the ‘read’ function of the model to get the data, but since I’m using an OData v4 service this isn’t available to me as far as I understood.

Any help or tips would be greatly appreciated

Visual Studio Script Documents Delay

Working on javascript projects in Visual Studio is frustrating due to all library scripts being opened in Script Documents. Whenever I make a change to a source file (JS,TS,HTML,CSS etc) all scripts must reload, which will freeze Visual Studio for some time.

This is more tolerable when using the inbuilt React template, as changes to TSX are hot-reloaded. I am currently trying out Lit + Shoelace with Vite, and the experience is almost unusable.

Anyway to get the hot-reload behaviour on non-React projects? Or anyway in general to mitigate delay?
Script Documents

Create a link having JSTL variable

I try to create a link by using javascript and I got some errors

document.addEventListener("DOMContentLoaded", function() {
  const token = localStorage.getItem('token'); // Lấy token từ localStorage
  const navLinks = document.getElementById('nav-links'); // Lấy phần tử nav chứa các liên kết
  const contextPath = window.location.pathname.substring(0, window.location.pathname.indexOf("/", 2)); // Lấy context path

  if (token) {
    fetch('/api/jwt/getName', {
        method: 'GET',
        headers: {
          'Authorization': 'Bearer ' + token,
          'Content-Type': 'application/json'
        }
      })
      .then(response => response.json())
      .then(data => {
        if (data && data.username) {
          const name = data.username; // Assign username from API
          console.log(name);

          navLinks.innerHTML = '';

          // Sử dụng template literals để chèn giá trị `name` từ JavaScript
          const profileLinkValue = `<a class="nav-link" href="${contextPath}/profile">${name}</a>`;

          // Tạo phần tử `li` chứa liên kết profile
          const profileLink = document.createElement('li');
          profileLink.classList.add('nav-item');
          profileLink.innerHTML = profileLinkValue;
          navLinks.appendChild(profileLink);

          // Tạo phần tử giỏ hàng và logout
          const cartLink = document.createElement('li');
          cartLink.classList.add('nav-item');
          cartLink.innerHTML = `
                    <a class="nav-link" href="${contextPath}/shopping_cart">
                        <img src="/image/shopping-cart.png" alt="Shopping cart" width="35" height="30">
                    </a>
                `;
          navLinks.appendChild(cartLink);

          const logoutLink = document.createElement('li');
          logoutLink.classList.add('nav-item');
          logoutLink.innerHTML = `<a class="nav-link" href="${contextPath}/logout">Logout</a>`;
          navLinks.appendChild(logoutLink);
        }
      })
      .catch(error => {
        console.error('Error fetching user info:', error);
      });
  }
});

When I run the web server,the page look like this

enter image description here

The problem here is, the profileLink should show the real account name, not the word ‘name’.

I have tried to log something, and I found the api works fine.
The problem I think is just the jstl variable ${name} in the link.
Could someone tell me the proper syntax for this? Thanks!

Edit : I have hardcored the value of the link as Example Name, and it’s the result

https://drive.google.com/file/d/1Wh1uUq0CMO8ExZv_soqMMsyIjQkwx968/view?usp=sharing

 navLinks.innerHTML = `
   <li class="nav-item"><a class="nav-link" href="${pageContext.request.contextPath}/profile">ExampleName</a></li>
   <li class="nav-item">
     <a class="nav-link" href="${pageContext.request.contextPath}/shopping_cart">
       <img src="/image/shopping-cart.png" alt="Shopping cart" width="35" height="30">
     </a>
   </li>
   <li class="nav-item"><a class="nav-link" href="${pageContext.request.contextPath}/logout">Logout</a></li>
  `;
}

and it showed like the pic above, so I think the real problem is ${data.username}.

[Create a link having JSTL varible]

I try to create a link by using javascript and I got some errors

<script>
    document.addEventListener("DOMContentLoaded", function () {
        const token = localStorage.getItem('token');  // Lấy token từ localStorage
        const navLinks = document.getElementById('nav-links');  // Lấy phần tử nav chứa các liên kết
        const contextPath = window.location.pathname.substring(0, window.location.pathname.indexOf("/", 2)); // Lấy context path

        if (token) {
            fetch('/api/jwt/getName', {
                method: 'GET',
                headers: {
                    'Authorization': 'Bearer ' + token,
                    'Content-Type': 'application/json'
                }
            })
                .then(response => response.json())
                .then(data => {
                    if (data && data.username) {
                        const name = data.username; // Assign username from API
                        console.log(name); 

                        navLinks.innerHTML = '';

                        // Sử dụng template literals để chèn giá trị `name` từ JavaScript
                        const profileLinkValue = `<a class="nav-link" href="${contextPath}/profile">${name}</a>`;

                        // Tạo phần tử `li` chứa liên kết profile
                        const profileLink = document.createElement('li');
                        profileLink.classList.add('nav-item');
                        profileLink.innerHTML = profileLinkValue;
                        navLinks.appendChild(profileLink);

                        // Tạo phần tử giỏ hàng và logout
                        const cartLink = document.createElement('li');
                        cartLink.classList.add('nav-item');
                        cartLink.innerHTML = `
                    <a class="nav-link" href="${contextPath}/shopping_cart">
                        <img src="/image/shopping-cart.png" alt="Shopping cart" width="35" height="30">
                    </a>
                `;
                        navLinks.appendChild(cartLink);

                        const logoutLink = document.createElement('li');
                        logoutLink.classList.add('nav-item');
                        logoutLink.innerHTML = `<a class="nav-link" href="${contextPath}/logout">Logout</a>`;
                        navLinks.appendChild(logoutLink);
                    }
                })
                .catch(error => {
                    console.error('Error fetching user info:', error);
                });
        }
    });

</script>

When I run the web server,the page look like this
enter image description here
The problem here is, the profileLink should show the real account name, not the word ‘name’.

I have tried to log something, and I found the api works fine.
The problem I think is just the jstl variable ${name} in the link.
Could someone tell me the proper syntax for this? Thanks!

Edit : I have hardcored the value of the link as Example Name, and it’s the result

https://drive.google.com/file/d/1Wh1uUq0CMO8ExZv_soqMMsyIjQkwx968/view?usp=sharing

 navLinks.innerHTML = `
                                           <li class="nav-item"><a class="nav-link" href="${pageContext.request.contextPath}/profile">ExampleName</a></li>
                        <li class="nav-item"><a class="nav-link" href="${pageContext.request.contextPath}/shopping_cart">
                            <img src="/image/shopping-cart.png" alt="Shopping cart" width="35" height="30">
                        </a></li>
                        <li class="nav-item"><a class="nav-link" href="${pageContext.request.contextPath}/logout">Logout</a></li>
                    `;
                    }

and it showed like the pic above, so I think the real problem is ${data.username}.