How can I persist user authentication after a token refresh in a React application using axios interceptors?

I am currently using axios interceptors to refresh an expired access token and refresh token from the server, which are stored in localStorage and cookies respectively. However, after the new access token is generated, I get logged out from the application. I am also using cookies to store user roles, which are used to protect routes using react-router-dom.

I have tried different methods to fix this issue, but it still occurs. How can I ensure that the user stays authenticated after a token refresh in my React application?
Here is the code:

export default function useRefreshToken() {
  const refresh = async () => {
    // gets the refresh token from cookies
    const refresh_token = getRefreshToken();
    try {
      const response = await axios.post("/api/refresh", null, {
        headers: {
          Authorization: `Bearer ${refresh_token}`,
        },
      });

      const accessToken = response.data.access_token;
      const refreshToken = response.data.refresh_token;

      console.log("New access token:", accessToken);
      console.log("New refresh token:", refreshToken);

      // sets the new access token and refresh token to localStorage and cookies
      setTokens(accessToken, refreshToken);

      return accessToken;

    } catch (error) {
      throw new Error(error);
    }
  };
  return refresh;
}

Here is the axios interceptors code:

export default function useAxiosPrivate() {
  const refresh = useRefreshToken();
  
  useEffect(() => {

    const requestIntercept = axiosPrivate.interceptors.request.use(
      (config) => {
        const accessToken = getAccessToken();
        if (accessToken) {
          config.headers['Authorization'] = `Bearer ${accessToken}`;
        }
        return config;
      },
      (error) => Promise.reject(error)
    );

    const responseIntercept = axiosPrivate.interceptors.response.use(
      (response) => response,
      async (error) => {
        const originalConfig = error?.config;
        if (error?.response?.status === 401 || 403  && !originalConfig?._retry) {
          originalConfig._retry = true;
          try {
            const newAccessToken = await refresh();
            console.log("Applying new access token:", newAccessToken);
            originalConfig.headers['Authorization'] = `Bearer ${newAccessToken}`;
            const newResponse = await axiosPrivate(originalConfig);
            return newResponse;

          } catch (error) {
            throw new Error (error);
          }
        }
        return Promise.reject(error);
      }
    );

    return () => {
      axiosPrivate.interceptors.request.eject(requestIntercept);
      axiosPrivate.interceptors.response.eject(responseIntercept);
    };
  }, [refresh]);

  return axiosPrivate;
}

I’m getting an undefined error after api call

I’m building a real estate website(off a youtube vid) and im getting undefined erros when fetching data from an api, I should mention that when fetching the data locally everything works fine.

export const usePropertyFormat = (property) => {
  const address = property.location.map((item) => item.name).join(", ");
  const coverPhoto = property.coverPhoto.url;
  const propertyType = `${property.category[0].name},${property.category[1].name}`;
  const price = property.price.toLocaleString("en-US", {
    style: "currency",
    currency: "USD",
    maximumFractionDigits: 0,
  });

  const title = property.title;
  const rooms = property.rooms;
  const baths = property.baths;
  const purpose = property.purpose;
  const sqSize = property.area.toFixed(2);
  const externalID = property.externalID;

  const photos = property.photos?.map((photo) => photo.url) || [];
  const description = property.description;
  const coverVideoUrl = property.coverVideo.url;
  const coverVideo = coverVideoUrl.slice(coverVideoUrl.length - 11);
  const panorama = property.panoramas?.length ? property.panoramas[0].url : [];

  const amenities = property.amenities
    ?.flatMap(({ amenities }) => amenities)
    .map((item) => item && item.text);

  const furnished = property.furnishingStatus;

  return {
    address,
    coverPhoto,
    propertyType,
    price,
    title,
    rooms,
    baths,
    purpose,
    sqSize,
    externalID,
    photos,
    description,
    coverVideo,
    panorama,
    amenities,
    furnished,
  };
};

This is the data file.

import { axios } from "@/lib/axios";

export const getProperties = async (num) => {
  const { data } = await axios.get("/properties/list", {
    params: {
      locationExternalIDs: "5002,6020",
      purpose: "for-sale",
      hitsPerPage: num,
      lang: "en, es",
      sort: "city-level-score",
      hasVideo: true,
      hasFloorPlan: true,
      hasPanorama: true,
    },
  });
  return data.hits;
};

This is the api to get the data.

import DefaultLayout from "@/features/Layout/DefaultLayout/DefaultLayout";
import { usePropertyFormat } from "@/features/common/Hooks/usePropertyFormat";
import {
  Badge,
  Box,
  Flex,
  Grid,
  GridItem,
  SimpleGrid,
  Text,
} from "@chakra-ui/react";
import { TbMapPin } from "react-icons/tb";
import PropertyThumbnailSlider from "@/features/Property/components/PropertyThumbnailSlider/propertyThumbnailSlider";
import PropertyStats from "@/features/Property/components/PropertyStats/PropertyStats";
import TextContextBox from "@/features/common/modules/TextContentBox/TextContentBox";
import PropertyYoutubeEmbed from "@/features/Property/components/PropertyYoutubeEmbed/PropertyYoutubeEmbed";
import PropertyMatterPortContent from "@/features/Property/components/PropertyMatterPortContent/PropertyMatterPortContent";
import { getProperty } from "@/features/Property/components/api/getProperty";

const PropertySingle = ({ property }) => {
  const {
    address,
    coverPhoto,
    propertyType,
    price,
    title,
    rooms,
    baths,
    purpose,
    sqSize,
    externalID,
    photos,
    description,
    coverVideo,
    panorama,
    amenities,
    furnished,
  } = usePropertyFormat(property);

  return (
    <DefaultLayout>
      <Box backgroundColor="#f7f8f9" paddingY="3rem">
        <Grid
          templateColumns={"repeat(6, 1fr)"}
          gap="5"
          maxWidth={"1280px"}
          margin={"0 auto"}
        >
          <GridItem colSpan={"6"}>
            <Text
              fontSize={"3xl"}
              fontWeight={"medium"}
              color={"blue.800"}
              textAlign={{ base: "center", sm: "left" }}
            >
              {propertyType} {title}
            </Text>
            <Flex
              fontSize={"xl"}
              color={"blue.600"}
              textAlign={"center"}
              alignItems={"center"}
              flexDirection={{ base: "col", sm: "row" }}
              gap={".5rem"}
              marginY={{ base: "1rem", sm: "0" }}
            >
              <TbMapPin />
              <Text fontWeight={"light"}>
                {address} - id:{externalID}
              </Text>
              <Badge colorScheme="green">{purpose}</Badge>
            </Flex>
          </GridItem>
          <GridItem colSpan={{ base: 6, sm: 3 }}>
            <PropertyThumbnailSlider photos={photos}></PropertyThumbnailSlider>
          </GridItem>
          <GridItem colSpan={{ base: 6, sm: 3 }}>
            <PropertyStats
              rooms={rooms}
              baths={baths}
              price={price}
              sqSize={sqSize}
            />
            <TextContextBox title="Description">
              <Text
                fontWeight={"light"}
                color={"gray.600"}
                fontSize={"1rem"}
                noOfLines={"4"}
              >
                {description}
              </Text>
            </TextContextBox>
            <TextContextBox title={"Amenities"}>
              <SimpleGrid
                columns={{ base: 1, sm: 2 }}
                fontWeight={"light"}
                color={"gray.600"}
                fontSize={"1rem"}
              >
                {amenities?.length
                  ? amenities.map((item) => <Text>{item}</Text>)
                  : "Please contact us for more info"}
              </SimpleGrid>
            </TextContextBox>
          </GridItem>
          <GridItem colSpan={{ base: 6, sm: 3 }}>
            <TextContextBox title={"Video Walkthrough"}>
              <PropertyYoutubeEmbed coverVideo={coverVideo} />
            </TextContextBox>
          </GridItem>
          <GridItem colSpan={{ base: 6, sm: 3 }}>
            <TextContextBox title={"3D Tour"}>
              <PropertyMatterPortContent panorama={panorama} />
            </TextContextBox>
          </GridItem>
        </Grid>
      </Box>
    </DefaultLayout>
  );
};

export default PropertySingle;

export async function getServerSideProps(context) {
  const { id } = context.query;
  const property = await getProperty(id);
  // const property = require("@/features/data/property");

  return {
    props: { property: property },
  };
}

This is the file where I’m using the data.

Server Error TypeError: Cannot read properties of undefined (reading
‘map’)

This error happened while generating the page. Any console logs will
be displayed in the terminal window. Source
featurescommonHooksusePropertyFormat.js (2:36) @ map

1 | export const usePropertyFormat = (property) => {

2 | const address = property.location.map((item) => item.name).join(“, “);
| ^ 3 | const coverPhoto = property.coverPhoto.url; 4 | const propertyType =
${property.category[0].name},${property.category[1].name}; 5 |
const price = property.price.toLocaleString(“en-US”, { Call Stack
property pagesproperties[id].js (38:24) Show collapsed frames

This is the error im getting.

Im fairly new using react and chakra ui.

Thanks in advance.

VSCode how to Globally Ignore Parameter implicitly has an ‘any’ type for a Javascript Project?

I have a Svelte/Sveltekit project that is using plain javascript, not typescript.

In my jsconfig.json file, I have turned on checkJs so that VSCode will be able to highlight spelling errors in variable names with a red error line:

{
    "compilerOptions": {
      "checkJs": true,
      ...
    }
}

However, this is causing a warning for every parameter on every one of my functions:

Parameter implicitly has an 'any' type, but a better type may be inferred from usage.js(7044)

I know that I can 1) add an ignore line in front of every function or 2) add a comment indicating the type to every function. However I don’t want to do these.

I would like to disable warnings globally for this particular type of warning.

Is it possible? Either in jsconfig.json or in vscode ?

Unable to get Javascript app to display 4 images at the same time as button for a quiz

I am trying to get 4 images to show up into 4 buttons. I am only getting one at a time. I need it to all be at the same time and for all of it to change once on button is clicked. Possible problem in the onEvent or the first if statement. This is for an quiz app. The grading function will come later once I am able to get the dog images to appear together and the click to work for the quiz.

var allDogs = getColumn("Dogs", "Name");
var allDogsPicturesList = getColumn("Dogs", "Image");
var questionNumber;
var dogImage;
var dogName;
var correctDog;
var userChoice;
var score;
setScreen("startScreen");
onEvent("readyButton", "click", function( ) {
  setScreen("quizScreen");
  gameQuestionsAndEnd();
});
onEvent("dog1", "click", function( ) {
  userChoice = getImageURL("dog1");
  gameQuestionsAndEnd();
});
onEvent("dog2", "click", function( ) {
  userChoice = getImageURL("dog2");
  gameQuestionsAndEnd();
});
onEvent("dog3", "click", function( ) {
  userChoice = getImageURL("dog3");
  gameQuestionsAndEnd();
});
onEvent("dog4", "click", function( ) {
  userChoice = getImageURL("dog4");
  gameQuestionsAndEnd();
});
function gameQuestionsAndEnd(answerRight, answerWrong) {
    dogName =(randomNumber(0, allDogs.length-1));
    dogImage = (randomNumber(0,allDogsPicturesList.length-1));
    correctDog = allDogsPicturesList[dogName];
    answerRight = dogName;
    var box = randomNumber(1,4);
    setText("dogBeingGuessed", "Which dog is a " + "n" + allDogs[dogName]);
    for (var w = 0; w <= 10; w++) {
    setProperty("dog"+box, "image", allDogsPicturesList[dogName]);
    if ("dog1"==allDogs[dogName]) {
        setProperty("dog2", "image", getImageURL(randomNumber(0,allDogsPicturesList.length)));
        setProperty("dog3", "image", getImageURL(randomNumber(0,allDogsPicturesList.length)));
        setProperty("dog4", "image", getImageURL(randomNumber(0,allDogsPicturesList.length)));
      questionNumber = questionNumber+1;
    } else if ("dog2"==dogName) {
        setProperty("dog1", "image", getImageURL(randomNumber(0,allDogsPicturesList.length)));
        setProperty("dog3", "image", getImageURL(randomNumber(0,allDogsPicturesList.length)));
        setProperty("dog4", "image", getImageURL(randomNumber(0,allDogsPicturesList.length)));
      questionNumber = questionNumber+1;
    } else if ("dog3"==dogName) {
        setProperty("dog2", "image", getImageURL(randomNumber(0,allDogsPicturesList.length)));
        setProperty("dog1", "image", getImageURL(randomNumber(0,allDogsPicturesList.length)));
        setProperty("dog4", "image", getImageURL(randomNumber(0,allDogsPicturesList.length)));
      questionNumber = questionNumber+1;
    } else if ("dog4"==dogName) {
        setProperty("dog2", "image", getImageURL(randomNumber(0,allDogsPicturesList.length)));
        setProperty("dog3", "image", getImageURL(randomNumber(0,allDogsPicturesList.length)));
        setProperty("dog1", "image", getImageURL(randomNumber(0,allDogsPicturesList.length)));
      questionNumber = questionNumber+1;
    }
    if (answerRight==userChoice) {
    score = score+1;
  }
    if (answerWrong) {
    score = score-1;
      }
    questionNumber = questionNumber+1;
  }
    if (questionNumber==10) {
      setScreen("screen1");
    }
}

Tried working different event options.

i18n-js and React Native : Use json files instead of .js files for translations

In my react native app I’m using “i18n-js”: “^3.9.2” in order to have translations, I’m only able to get them to work properly using .js files for each locale like this:

es.js

export default 
{
    currency:"€",
    rememberToUnsuscribe:"Recuerda que si estas suscrito
}

It works fi ne but I’d like to use .json files instead of .js files, how can I do that? is it even possibe with this library?

This is my i18n.js file, where I bootstrap the translations.

import I18n from "i18n-js";
//import {  AsyncStorage  } from 'react-native';

import en from "@locales/en";
import es from "@locales/es";


I18n.fallbacks = true;
I18n.translations = {
  en,
  es
};

if (Array.isArray(locales)) 
{
    I18n.locale = locales[0].languageTag;
    console.log('I18n.locale',I18n.locale);
}

export default I18n;

Import private key from .p12 file to sign an XML file with XAdES using xadesjs

Hello everyone I’m using xadesjs specifically the XAdES-BES Signature,I’ve been following the steps of the documentation.

var xadesjs = require("xadesjs");
var { Crypto } = require("@peculiar/webcrypto");

xadesjs.Application.setEngine("NodeJS", new Crypto());

// Generate RSA key pair
var privateKey, publicKey;
xadesjs.Application.crypto.subtle.generateKey(
    {
        name: "RSASSA-PKCS1-v1_5",
        modulusLength: 1024, //can be 1024, 2048, or 4096,
        publicExponent: new Uint8Array([1, 0, 1]),
        hash: { name: "SHA-1" }, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
    },
    false, //whether the key is extractable (i.e. can be used in exportKey)
    ["sign", "verify"] //can be any combination of "sign" and "verify"
)
    .then(function (keyPair) {
        // Push ganerated keys to global variable
        privateKey = keyPair.privateKey;
        publicKey = keyPair.publicKey;

        // Call sign function
        var xmlString = '<player bats="left" id="10012" throws="right">nt<!-- Here's a comment -->nt<name>Alfonso Soriano</name>nt<position>2B</position>nt<team>New York Yankees</team>n</player>';
        return SignXml(xmlString, keyPair, { name: "RSASSA-PKCS1-v1_5", hash: { name: "SHA-1" } });
    })
    .then(function (signedDocument) {
        console.log("Signed document:nn", signedDocument);
    })
    .catch(function (e) {
        console.error(e);
    });


function SignXml(xmlString, keys, algorithm) {
    return Promise.resolve()
        .then(() => {
            var xmlDoc = xadesjs.Parse(xmlString);
            var signedXml = new xadesjs.SignedXml();

            return signedXml.Sign(               // Signing document
                algorithm,                              // algorithm
                keys.privateKey,                        // key
                xmlDoc,                                 // document
                {                                       // options
                    keyValue: keys.publicKey,
                    references: [
                        { hash: "SHA-256", transforms: ["enveloped"] }
                    ],
                    productionPlace: {
                        country: "Country",
                        state: "State",
                        city: "City",
                        code: "Code",
                    },
                    signingCertificate: "MIIGgTCCBGmgAwIBAgIUeaHFHm5f58zYv20JfspVJ3hossYwDQYJKoZIhvcNAQEFBQAwgZIxCzAJBgNVBAYTAk5MMSAwHgYDVQQKExdRdW9WYWRpcyBUcnVzdGxpbmsgQi5WLjEoMCYGA1UECxMfSXNzdWluZyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTE3MDUGA1UEAxMuUXVvVmFkaXMgRVUgSXNzdWluZyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBHMjAeFw0xMzEwMzAxMjI3MTFaFw0xNjEwMzAxMjI3MTFaMHoxCzAJBgNVBAYTAkJFMRAwDgYDVQQIEwdCcnVzc2VsMRIwEAYDVQQHEwlFdHRlcmJlZWsxHDAaBgNVBAoTE0V1cm9wZWFuIENvbW1pc3Npb24xFDASBgNVBAsTC0luZm9ybWF0aWNzMREwDwYDVQQDDAhFQ19ESUdJVDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJgkkqvJmZaknQC7c6H6LEr3dGtQ5IfOB3HAZZxOZbb8tdM1KMTO3sAifJC5HNFeIWd0727uZj+V5kBrUv36zEs+VxiN1yJBmcJznX4J2TCyPfLk2NRELGu65VwrK2Whp8cLLANc+6pQn/5wKh23ehZm21mLXcicZ8whksUGb/h8p6NDe1cElD6veNc9CwwK2QT0G0mQiEYchqjJkqyY8HEak8t+CbIC4Rrhyxh3HI1fCK0WKS9JjbPQFbvGmfpBZuLPYZYzP4UXIqfBVYctyodcSAnSfmy6tySMqpVSRhjRn4KP0EfHlq7Ec+H3nwuqxd0M4vTJlZm+XwYJBzEFzFsCAwEAAaOCAeQwggHgMFgGA1UdIARRME8wCAYGBACLMAECMEMGCisGAQQBvlgBgxAwNTAzBggrBgEFBQcCARYnaHR0cDovL3d3dy5xdW92YWRpc2dsb2JhbC5ubC9kb2N1bWVudGVuMCQGCCsGAQUFBwEDBBgwFjAKBggrBgEFBQcLAjAIBgYEAI5GAQEwdAYIKwYBBQUHAQEEaDBmMCoGCCsGAQUFBzABhh5odHRwOi8vb2NzcC5xdW92YWRpc2dsb2JhbC5jb20wOAYIKwYBBQUHMAKGLGh0dHA6Ly90cnVzdC5xdW92YWRpc2dsb2JhbC5jb20vcXZldWNhZzIuY3J0MEYGCiqGSIb3LwEBCQEEODA2AgEBhjFodHRwOi8vdHNhMDEucXVvdmFkaXNnbG9iYWwuY29tL1RTUy9IdHRwVHNwU2VydmVyMBMGCiqGSIb3LwEBCQIEBTADAgEBMA4GA1UdDwEB/wQEAwIGQDAfBgNVHSMEGDAWgBTg+A751LXyf0kjtsN5x6M1H4Z6iDA7BgNVHR8ENDAyMDCgLqAshipodHRwOi8vY3JsLnF1b3ZhZGlzZ2xvYmFsLmNvbS9xdmV1Y2FnMi5jcmwwHQYDVR0OBBYEFDc3hgIFJTDamDEeQczI7Lot4uaVMA0GCSqGSIb3DQEBBQUAA4ICAQAZ8EZ48RgPimWY6s4LjZf0M2MfVJmNh06Jzmf6fzwYtDtQLKzIDk8ZtosqYpNNBoZIFICMZguGRAP3kuxWvwANmrb5HqyCzXThZVPJTmKEzZNhsDtKu1almYBszqX1UV7IgZp+jBZ7FyXzXrXyF1tzXQxHGobDV3AEE8vdzEZtwDGpZJPnEPCBzifdY+lrrL2rDBjbv0VeildgOP1SIlL7dh1O9f0T6T4ioS6uSdMt6b/OWjqHadsSpKry0A6pqfOqJWAhDiueqgVB7vus6o6sSmfG4SW9EWW+BEZ510HjlQU/JL3PPmf+Xs8s00sm77LJ/T/1hMUuGp6TtDsJe+pPBpCYvpm6xu9GL20CsArFWUeQ2MSnE1jsrb00UniCKslcM63pU7I0VcnWMJQSNY28OmnFESPK6s6zqoN0ZMLhwCVnahi6pouBwTb10M9/Anla9xOT42qxiLr14S2lHy18aLiBSQ4zJKNLqKvIrkjewSfW+00VLBYbPTmtrHpZUWiCGiRS2SviuEmPVbdWvsBUaq7OMLIfBD4nin1FlmYnaG9TVmWkwVYDsFmQepwPDqjPs4efAxzkgUFHWn0gQFbqxRocKrCsOvCDHOHORA97UWcThmgvr0Jl7ipvP4Px//tRp08blfy4GMzYls5WF8f6JaMrNGmpfPasd9NbpBNp7A=="
                })
            })
            .then(signature => signature.toString());
}

In this example they show you how to sign an XML file with XAdESBES, but in the example they generate the private key and the public key. I want to import my own private key from a .p12 file and sign the XML file

I’ve implemented the following code based on the examples of the documentation of the repository and have the following error:

My implementation to read my private key from the .p12 file and try to sign the xml file

const fs = require("fs");
var { Crypto } = require("@peculiar/webcrypto");
const xadesjs = require("xadesjs");
const { XMLSerializer } = require("xmldom");

const crypto = new Crypto();
xadesjs.Application.setEngine("NodeJS", new Crypto());

// Hash and algorith from the example
const hash = "SHA-1";
const alg = {
  name: "RSASSA-PKCS1-v1_5",
  hash,
};

function preparePem(pem) {
  return (
    pem
      // remove BEGIN/END
      .replace(/-----(BEGIN|END)[wds]+-----/g, "")
      // remove r, n
      .replace(/[rn]/g, "")
  );
}

function pem2der(pem) {
  pem = preparePem(pem);
  // convert base64 to ArrayBuffer
  return new Uint8Array(Buffer.from(pem, "base64")).buffer;
}

// Set the path of the  .p12 file
const path = require("path");
const p12Path = path.resolve(__dirname, "cert.p12");

//Read key
const keyPem = fs.readFileSync(p12Path, { encoding: "utf-8" });
const keyDer = pem2der(keyPem);

//Retrieve the key to sign the document
const key = xadesjs.Application.crypto.subtle.importKey(
  "pkcs8",
  keyDer,
  alg,
  false,
  ["sign"]
);

The Error:

            throw new Error(asn1Parsed.result.error);
                  ^

Error: End of input reached before message was fully decoded (inconsistent offset and length values)
    at Function.parse (/home/baeto/Documents/xades/node_modules/@peculiar/asn1-schema/build/cjs/parser.js:14:19)
    at Function.importKey (/home/baeto/Documents/xades/node_modules/@peculiar/webcrypto/build/webcrypto.js:863:54)
    at RsaSsaProvider.onImportKey (/home/baeto/Documents/xades/node_modules/@peculiar/webcrypto/build/webcrypto.js:1036:37)
    at RsaSsaProvider.importKey (/home/baeto/Documents/xades/node_modules/webcrypto-core/build/webcrypto-core.js:234:33)
    at SubtleCrypto.importKey (/home/baeto/Documents/xades/node_modules/webcrypto-core/build/webcrypto-core.js:1475:29)
    at Object.<anonymous> (/home/baeto/Documents/xades/index.js:42:47)
    at Module._compile (node:internal/modules/cjs/loader:1105:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)

I am trying to make a survey of answers to questions and cannot add each response to the responses

I am trying to capture the users responses to survey questions. Each individual state is reflecting the changes, But when I try to add them to the array of responses, it just never works. I have tried everything I found online to no avail… help please!!!

Data looks like this after the await runs
[{key:”1″, colWidth:”8″, questionType:’Multiple Choice’, text: ‘What is your favorite color?’,choices: [{‘distractorID’:1,’distractorText’:’Red’},{‘distractorID’:2,’distractorText’:’Green’},{‘distractorID’:3,’distractorText’:’Blue’},
{‘distractorID’:4,’distractorText’:’Orange’},{‘distractorID’:5,’distractorText’:’Gold’},
{‘distractorID’:6,’distractorText’:’Pink’}]},{key:”2″, colWidth:”6″, questionType:’Rating’, text: ‘on a scale of 1 to 10 how good was this program?’, choices:””, numStars: 10},
{key:”3″, colWidth:”6″, questionType:’Text’, text: ‘What is your favorite part of the day?’, choices:””, numStars: 0},{key:”4″, colWidth:”8″, questionType:’Multiple Choice’, text: ‘Do you enjoy good food?’, choices: [{‘distractorID’:7,’distractorText’:’Yes’},{‘distractorID’:8,’distractorText’:’No’}],”numStars”:0},{key:”5″, colWidth:”8″, questionType:’Multiple Choice’, text: ‘I like broccoli?’, choices: [{‘distractorID’:9,’distractorText’:’False’},’distractorID’:10,’distractorText’:’True’}],”numStars”:0},{key:”6″, colWidth:”8″, questionType:’Multiple Choice’, text: ‘I would do this again’, choices [{‘distractorID’:11,’distractorText’:’False’},’distractorID’:12,’distractorText’:’True’}],”numStars”:0}]

        import './App.css';
        import  { React, useEffect, useState } from 'react';
        import TextBox from "./components/TextBox";
        import StarRating from './components/StarRating';
        import Question from './components/Question';
        import 'bootstrap/dist/css/bootstrap.min.css';
        import 'bootstrap/dist/js/bootstrap';
        
        
        function App(props) 
          {
          const orgID = 29;
        
          const userID = 106580;
          // eslint-disable-next-line
          const sid = /[^/]*$/.exec(document.location)[0];
        
          const today = new Date().toLocaleDateString('pt-br').split( '/' ).reverse( ).join( '-' );
        
          const [ questions, setQuestions ] = useState([]);
        
          const [ responses, setResponses] = useState([]);
        
          const [ theresponse, setTheresponse] = useState (
              {
              responseID:0,
              surveyId:parseInt(sid),
              questionID: 0,
              distractorID:"",
              responseText: 0 ,
              userID: parseInt(userID),
              orgID: parseInt(orgID),
              lastEditor: parseInt(userID),
              lastEditDate: today
              }
            );
        
         function displayResults() 
             {
             console.log(JSON.stringify(responses));
             }
        
          // update the state for a rating change
          function handleRatingChange(rating, questionid) {
            //set the individual state  
            setTheresponse(prevState => 
              ({ ...prevState,
                  responseID:0,
                  surveyId:parseInt(sid),
                  questionID: parseInt(questionid),
                  distractorID:"",
                  responseText: parseInt(rating) ,
                  userID: parseInt(userID),
                  orgID: parseInt(orgID),
                  lastEditor: parseInt(userID),
                  lastEditDate: today,
              }));
              //set the group state 
            setResponses(prevState => ({ ...prevState,
                ...theresponse,
              }));
            }
        
          function handleAnswerChange(questionid, answer, key) 
            {
            setTheresponse(prevState => ({ ...prevState,
              responseID:0,
              questionID: questionid,
              distractorID:parseInt(key),
              responseText: answer,
              }));
            //set the group state 
            setResponses(prevState => ({ ...prevState,
                ...theresponse,
              }));
            }
          
          // update the state for the text field being changed
          function handleTextChange(qid, answer) 
            {
            //set the individual state
            setTheresponse(prevState => ({ ...prevState,
                responseID:0,
                questionID: parseInt(qid),
                distractorID:"",
                responseText: answer,
              }));
            //set the group state 
            setResponses(prevState => ({ ...prevState,
                ...theresponse,
              }));
            }
        
            useEffect(() => 
            {
            const fetchData = async () => {
          
              const response = await fetch(
                `http://localhost:5000/getQuestionsForJson/${sid}`);
                 const data = await response.json();
                 //use only 3 sample data
                 setQuestions( data );
              }
          
              // Call the function
              fetchData();
            }, []);
        
        
        
            return (
              <div>
                {questions.map((data) => {
                  switch (data.questionType) {
                    case 'Text':
                      return <TextBox 
                      colWidth={data.colWidth}                    // col-md-{colWidth}
                      key={data.key}                              // questionID
                      question={data.text}                        // questionText
                      onAnswerChange={handleTextChange}           // Selection event
                      />
                    case 'Rating Scale':
                      return <StarRating 
                      colWidth={data.colWidth}                    // col-md-{colWidth}
                      questionid={data.key}                       // questionID
                      key={data.key}                              // questionID
                      question={data.text}                        // questionText
                      numStars={data.numStars}                    // number of stars
                      onRatingChange={handleRatingChange}         // selection event
                      />
                    case 'Multiple Choice':
                      return <Question 
                      colWidth={data.colWidth}                    // col-md-{colWidth}
                      key={data.key}                              // questionID
                      questionType="multiple choice"              // questionType
                      question={data}                             // questionText
                      onAnswerChange={handleAnswerChange}         // Selection Event
                      />
                    default:
                      return <div>Type Not Found</div>
                    }  
                  })}
                  <div className='container col-md-2'>
                    <br/><br/>
                    <button type="button" onClick={displayResults} className="btn btn-primary">Save</button>&nbsp;
                    <button type="button" className="btn btn-warning">Cancel</button>
                  </div>
                </div>
            );
          }
        
        export default App;

When I run it the array of responses always only has the last one done I am trying to have an array of responses to the survey questions so that I can submit the once amd either they all make it or they all fail.

ERR_CACHE_MISS: going to previous page need reloading

I am building a website using GAS, after logging-in with a valid user name and password, everything seems to work fine, when returning to previous page, the page fails to load with an error regarding ERRCACHEMISS.

To be able to actually load the page i need to refresh, causing a less smooth flow.

Any ideas?

I tried to disable cache from the console, it actually solves the problem, but once the console is closed the problem comes back.

How to Drag a slider using javascript

I am new in web development field i face javascript slider issue. .

Slider working fine issue is slider not slide when we drag the slide
This is the website link https://bwiairport.wpengine.com/

Drag a slide to next slide
Below code attached

Slider is getting data fully dynamic this website design in custom wordpress template

Php Code also attched


<?php 
$slides = get_sub_field('slide');
// print_r($slides);
$no_slides = count($slides);

// print_r('</br> No of slides '.$no_slides);
?>
<style>

.mySlides {display: none}
img {vertical-align: middle;}
.fade:not(.show) {
    opacity: 1;
}
/* Slideshow container */
.slideshow-container {
  max-width: 100%;
  position: relative;
  margin: auto;
  /*height: calc(100vh - 221px);*/
    overflow: hidden;
    margin-top: 50px;
}

/* Next & previous buttons */
.prev, .next {
  cursor: pointer;
  position: absolute;
  width: auto;
  padding: 16px;
  margin-top: -22px;
  color: white;
  font-weight: bold;
  font-size: 18px;
  transition: 0.6s ease;
  border-radius: 0 3px 3px 0;
  user-select: none;
  bottom: 5%;
}

/* Position the "next button" to the right */
.next {
  right: 0;
  border-radius: 3px 0 0 3px;
}

/* On hover, add a black background color with a little bit see-through */
.prev:hover, .next:hover {
  background-color: rgba(0,0,0,0.8);
}

/* Caption text */
.text {
  color: #f2f2f2;
  font-size: 15px;
  padding: 8px 180px;
  position: absolute;
  bottom: 8px;
  width: 100%;
  text-align: center;
}

/* Number text (1/3 etc) */
.numbertext {
  color: #f2f2f2;
  font-size: 12px;
  padding: 8px 12px;
  position: absolute;
  top: 0;
}

/* The dots/bullets/indicators */
.dot {
  cursor: pointer;
  height: 15px;
  width: 15px;
  margin: 0 2px;
  background-color: #bbb;
  border-radius: 50%;
  display: inline-block;
  transition: background-color 0.6s ease;
}

.active, .dot:hover {
  background-color: #717171;
}

/* Fading animation */
.fade {
  animation-name: fade;
  animation-duration: 1.5s;
}

.slider_link a {
    font-size: 2.25rem;
    line-height: 1.16667;
    font-weight: 700;
    color: #ffffff;
}
.mySlides p {
    font-size: 1.3125rem !important;
    line-height: 1.33333;
    margin-top: 15px;
    color: #ffffff;
}
span.dot {
    width: 14px;
    height: 14px;
    background-color: rgba(0,0,0,0.4);
    border-radius: 50%;
    box-shadow: inset 0 0 0 1px #fff;
    content: '';
    display: inline-block; 
    overflow: hidden;
    transition: background-color 0.25s;
        margin: 2px;
}
span.dot.active {
    background-color: #fff;
}
.slider_bullets {
    position: absolute;
    bottom: 30%;
    left: 0;
    right: 0;
}
a.nav_arrows {
    width: 55px;
    height: 55px;
    display: flex;
    align-items: center;
    background: rgba(0,0,0,0.9);
    box-shadow: inset 0px 0px 0px 4px #fff;
    border-radius: 50%;
    color: #fff;
    justify-content: center;
    pointer-events: auto;
    text-indent: -9999px;
    transition: background-color 0.25s,box-shadow 0.25s;
    will-change: transform;
}
a.nav_arrows:hover {
    box-shadow: inset 0px 0px 0px 1px #fff;
    background: rgba(0,0,0,0.4);
}
a.nav_arrows svg {
    width: 19 !important;
    height: 22 !important;
}
.mySlides.fade:before {
    height: 100%;
    width: 100%;
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 0;
    background: linear-gradient(to top,rgba(0,0,0,0.75),transparent 65%);
    content: '';
}
@keyframes fade {
  from {opacity: .4} 
  to {opacity: 1}
}

/* On smaller screens, decrease text size */
@media only screen and (max-width: 300px) {
  .prev, .next,.text {font-size: 11px}
}
</style>


    <div class="slideshow-container">
        <?php foreach($slides as $slide ){ 
            $img = $slide['image']['url'];
            $video = $slide['video']['url'];
            $link = $slide['link'];
            $sub_caption = $slide['sub_caption'];
            ?>

        <div class="mySlides fade">
        <a href="<?php echo $link['url']; ?>"><?php if($img != ''){ ?>
                <img src="<?php echo $img; ?>" style="width:100%">
          <?php } ?></a>
          <?php if($video != ''){ ?>
          <video width="100%" autoplay loop muted>
              <source src="<?php echo $video; ?>" type="video/mp4">
          </video>
          <?php } ?>
          <div class="text">

        <?php if($link != ''){  ?>
            <div class="slider_link"><a href="<?php echo $link['url']; ?>"><?php echo $link['title']; ?></a></div>
        <?php } 
        if($sub_caption != ''){ ?>
            <p><?php echo $sub_caption; ?></p>
        <?php } ?>
          </div>
        </div>
        <?php } ?>

        <a class="nav_arrows prev" onclick="plusSlides(-1)" aria-label="Previous"><span class="icon"><svg class="symbol symbol_feature_left"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#feature_left"></use></svg></span></a>
        <a class="nav_arrows next" onclick="plusSlides(1)" aria-label="Next"><svg class="symbol symbol_feature_right"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#feature_right"></use></svg></a>

        <div class="slider_bullets" style="text-align:center" aria-label="carousel pagination">
          <?php for($i=1; $i <= $no_slides; $i++ ){ ?>
          <span class="dot" onclick="currentSlide(<?php echo $i; ?>)"></span> 
          <?php } ?>
        </div>

    </div>


<script>
let slideIndex = 1;
showSlides(slideIndex);

function plusSlides(n) {
  showSlides(slideIndex += n);
}

function currentSlide(n) {
  showSlides(slideIndex = n);
}

function showSlides(n) {
  let i;
  let slides = document.getElementsByClassName("mySlides");
  let dots = document.getElementsByClassName("dot");
  if (n > slides.length) {slideIndex = 1}    
  if (n < 1) {slideIndex = slides.length}
  for (i = 0; i < slides.length; i++) {
    slides[i].style.display = "none";  
  }
  for (i = 0; i < dots.length; i++) {
    dots[i].className = dots[i].className.replace(" active", "");
  }
  slides[slideIndex-1].style.display = "block";  
  dots[slideIndex-1].className += " active";
}



</script>
<script>
    slideshow-container.addEventListener("mousemove", (e) => {
   if (!isPressed) return;
   e.preventDefault();
   myslides.style.left = `${e.offsetX - cursorX}px`;
});
</script>

Docker build keeps failing

I am trying to deploy my node.js application using docker. I keep getting this error:
the command /bin/sh -c npm run build --prefix backend returned a non-zero code: 1.

The node.js is written in typescript. Here is my docker file:

I don’t know what I’m doing wrong but it is my first time of using typescript with docker for deployment

## multi stage system
FROM node:lts-alpine

WORKDIR /app

COPY package*.json ./ 

COPY backend/package*.json backend/

RUN npm run install-backend 

RUN npm run backend-build


## this is stage two , where the app actually runs
FROM node:lts-alpine

WORKDIR /app
COPY package*.json ./ 

COPY backend/package*.json backend/ 

RUN npm run install-backend --only=production


COPY ./build ./build

RUN npm install pm2 -g

USER node

CMD ["pm2-runtime", "ecosystem.config.js"]

EXPOSE 5000

Here is my root package.json file:

{
  "name": "chickeneat",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "install-backend": "npm install --prefix backend",
    "backend-dev": "npm dev --prefix backend",
    "backend-production": "npm production --prefix backend",
    "backend-build": "npm run build --prefix backend"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

And here is my server package.json file

{
  "name": "backend",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "ts-node-dev --respawn src/server.ts",
    "build": "tsc",
    "production": "node src/build/src/server.js"
  },
  "keywords": [],
  "author": "Kingsley Okoro <kingswebapp>",
  "license": "ISC",
  "devDependencies": {
    "@types/bcrypt": "^5.0.0",
    "@types/express": "^4.17.15",
    "@types/jsonwebtoken": "^9.0.0",
    "dotenv": "^16.0.3",
    "ts-node-dev": "^2.0.0",
    "typescript": "^4.9.4"
  },
 
}

I was asked to provide the entire log: Here it is. The OS is linux on Ubuntu

npm run build --prefix backend


> [email protected] build
> tsc

Version 4.9.4
tsc: The TypeScript Compiler - Version 4.9.4

COMMON COMMANDS

  tsc
  Compiles the current project (tsconfig.json in the working directory.)

  tsc app.ts util.ts
  Ignoring tsconfig.json, compiles the specified files with default compiler options.

  tsc -b
  Build a composite project in the working directory.

  tsc --init
  Creates a tsconfig.json with the recommended settings in the working directory.

  tsc -p ./path/to/tsconfig.json
  Compiles the TypeScript project located at the specified path.

  tsc --help --all
  An expanded version of this information, showing all possible compiler options

  tsc --noEmit
  tsc --target esnext
  Compiles the current project, with additional settings.

COMMAND LINE FLAGS

--help, -h
Print this message.

--watch, -w
Watch input files.

--all
Show all compiler options.

--version, -v
Print the compiler's version.

--init
Initializes a TypeScript project and creates a tsconfig.json file.

--project, -p
Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.

--build, -b
Build one or more projects and their dependencies, if out of date

--showConfig
Print the final configuration instead of building.

COMMON COMPILER OPTIONS

--pretty
Enable color and formatting in TypeScript's output to make compiler errors easier to read.
type: boolean
default: true

--target, -t
Set the JavaScript language version for emitted JavaScript and include compatible library declarations.
one of: es3, es5, es6/es2015, es2016, es2017, es2018, es2019, es2020, es2021, es2022, esnext
default: es3

--module, -m
Specify what module code is generated.
one of: none, commonjs, amd, umd, system, es6/es2015, es2020, es2022, esnext, node16, nodenext
default: undefined

--lib
Specify a set of bundled library declaration files that describe the target runtime environment.
one or more: es5, es6/es2015, es7/es2016, es2017, es2018, es2019, es2020, es2021, es2022, esnext, dom, dom.iterable, webworker, webworker.importscripts, webworker.iterable, scripthost, es2015.core, es2015.collection, es2015.generator, es2015.iterable, es2015.promise, es2015.proxy, es2015.reflect, es2015.symbol, es2015.symbol.wellknown, es2016.array.include, es2017.object, es2017.sharedmemory, es2017.string, es2017.intl, es2017.typedarrays, es2018.asyncgenerator, es2018.asynciterable/esnext.asynciterable, es2018.intl, es2018.promise, es2018.regexp, es2019.array, es2019.object, es2019.string, es2019.symbol/esnext.symbol, es2019.intl, es2020.bigint/esnext.bigint, es2020.date, es2020.promise, es2020.sharedmemory, es2020.string, es2020.symbol.wellknown, es2020.intl, es2020.number, es2021.promise/esnext.promise, es2021.string, es2021.weakref/esnext.weakref, es2021.intl, es2022.array/esnext.array, es2022.error, es2022.intl, es2022.object, es2022.sharedmemory, es2022.string/esnext.string, esnext.intl
default: undefined

--allowJs
Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files.
type: boolean
default: false

--checkJs
Enable error reporting in type-checked JavaScript files.
type: boolean
default: false

--jsx
Specify what JSX code is generated.
one of: preserve, react, react-native, react-jsx, react-jsxdev
default: undefined

--declaration, -d
Generate .d.ts files from TypeScript and JavaScript files in your project.
type: boolean
default: `false`, unless `composite` is set

--declarationMap
Create sourcemaps for d.ts files.
type: boolean
default: false

--emitDeclarationOnly
Only output d.ts files and not JavaScript files.
type: boolean
default: false

--sourceMap
Create source map files for emitted JavaScript files.
type: boolean
default: false

--outFile
Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output.

--outDir
Specify an output folder for all emitted files.

--removeComments
Disable emitting comments.
type: boolean
default: false

--noEmit
Disable emitting files from a compilation.
type: boolean
default: false

--strict
Enable all strict type-checking options.
type: boolean
default: false

--types
Specify type package names to be included without being referenced in a source file.

--esModuleInterop
Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility.
type: boolean
default: false

You can learn about all of the compiler options at https://aka.ms/tsc

The command '/bin/sh -c npm run backend-build' returned a non-zero code: 1
kingsley@kingsley-VirtualBox:~/Desktop/code/chickenEat$ 

“Failed to load JSON sprite sheet in PixiJS: Error with JSON.parse unexpected character – How to resolve?”

Failed to create player animated sprite: Error: [Loader.load] Failed to load http://localhost:3004/sprites/playerSpritesheet.json.
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
    node_modules pixi/assets/lib/loader/Loader.mjs/load/promises<@http://localhost:3004/static/js/bundle.js:76516

I get the above error before the following statement is exected:

createPlayerAnimatedSprite().then(player => {

I looked up the latest Pixi.js documentation here: https://pixijs.download/dev/docs/PIXI.Spritesheet.html, but it doesn’t seem like there’s anything wrong with my JSON.

Could it even possibly be an issue with my development server not reading JSON? Just throwing things out there. What could be going wrong here?

Game.jsx:

import React, { useEffect, useRef } from 'react';
import * as PIXI from 'pixi.js';
import { AnimatedSprite, Assets, Spritesheet } from 'pixi.js';
import InputHandler from '../utils/InputHandler';
import { CANVAS_WIDTH, CANVAS_HEIGHT, PLAYER_SIZE, PLAYER_SPEED, GRAVITY, JUMP_HEIGHT, JUMP_SPEED } from '../utils/GameConstants';
import { platforms } from '../utils/Platforms'; // Corrected the import path here
import { createPlayerSprite, createPlatformSprites } from '../utils/CreateSprites';
const { PLAYER_COLOR_DEFAULT, PLAYER_COLOR_LEFT, PLAYER_COLOR_RIGHT, PLAYER_COLOR_JUMP, PLAYER_COLOR_DESCENT, PLAYER_COLOR_FALL_LEFT, PLAYER_COLOR_FALL_RIGHT } = require('../utils/PlayerAnimations');

// Define the collision detection class
const Bump = require('../utils/Bump');

// Define the paths to the sprite sheet JSON and the image file
const playerSpriteSheetPath = '../sprites/playerSpritesheet.json';
const playerSpriteSheetImage = '../assets/images/playerSpritesheet.png'; // Adjust this path based on your project

// Define the animation sequences using frame names from the sprite sheet
const animationSequences = {
  idle: ['idle_frame'],
  walkLeft: ['walk_left_1', 'walk_left_2'],
  walkRight: ['walk_right_1', 'walk_right_2'],
  jumpRight: ['jump_right'],
  jumpLeft: ['jump_left'],
  fallRight: ['fall_right'],
  fallLeft: ['fall_left'],
  shootRight: ['shoot_right'],
  shootLeft: ['shoot_left']
};

// Utility function to create an animated sprite from the sprite sheet
async function createPlayerAnimatedSprite() {
  // Load the sprite sheet JSON data using PIXI.Assets.load
  const spriteSheetData = await Assets.load(playerSpriteSheetPath);
  
  // Load the sprite sheet image using PIXI.Assets.load
  const spriteSheetImage = await Assets.load(playerSpriteSheetImage);
  
  // Instantiate a Spritesheet using the loaded image and JSON data
  const spriteSheet = new Spritesheet(spriteSheetImage, spriteSheetData);
  await spriteSheet.parse(); // Parse the sprite sheet to extract textures
  
  // Create an animated sprite with the idle frames
  const frames = animationSequences.idle.map(frameName => spriteSheet.textures[frameName]);
  const animatedSprite = new AnimatedSprite(frames);
  animatedSprite.animationSpeed = 0.1; // Set the animation speed
  animatedSprite.play(); // Start playing the animation
  return animatedSprite;
}

// Utility function to create a bullet sprite
function createBullet(PIXI, bulletWidth, bulletHeight) {
  const bullet = new PIXI.Graphics();
  bullet.beginFill(0x000000); // Bullet color (black)
  bullet.drawRect(0, 0, bulletWidth, bulletHeight); // Use bulletSize for width and height
  bullet.endFill();
  bullet.distanceTraveled = 0; // Add distanceTraveled property to the bullet and set to 0
  return bullet;
}

const Game = () => {
  const gameContainer = useRef(null);

  // Define dy in the outer scope
  let dy = 0;

  // Add a variable to store the player's last facing direction
  let lastFacingDirection = 'right';

  // Define the game area dimensions
  const GAME_WIDTH = CANVAS_WIDTH * 5;
  const GAME_HEIGHT = CANVAS_HEIGHT;

  const MAX_BULLET_DISTANCE = 1000; // Define the maximum distance a bullet can travel

  useEffect(() => {
    // Create PixiJS application and append to the game container
    const app = new PIXI.Application({
      width: CANVAS_WIDTH,
      height: CANVAS_HEIGHT,
      backgroundColor: 0xffffff,
    });
    gameContainer.current.appendChild(app.view);

    // Create a container to hold all game objects
    const gameScene = new PIXI.Container();
    app.stage.addChild(gameScene);

    // Create platform sprites using the createPlatformSprites function and assign them to the variable platformSprites
    const platformSprites = createPlatformSprites(PIXI, platforms);
    platformSprites.forEach(sprite => gameScene.addChild(sprite));

    // Initialize input handler
    const inputHandler = new InputHandler();

    // Create an instance of Bump
    const b = new Bump(PIXI);

    let bullets = []; // Array to store active bullet sprites
    const BULLET_SPEED = 5; // Speed of bullets



    // Create player animated sprite using the createPlayerAnimatedSprite function
    createPlayerAnimatedSprite().then(player => {
        console.log('Player sprite created:', player); // Add this log statement

        // Set initial position of the player object (modify as needed)
        player.x = CANVAS_WIDTH / 2;
        player.y = CANVAS_HEIGHT - PLAYER_SIZE;

        gameScene.addChild(player);
        console.log(player.x, player.y);


        // Inside the gameLoop function
        const gameLoop = (delta) => {
          console.log('Game loop running'); // Add this log statement

          const { x, y } = player;
          let newX = x;
          let newY = y + dy;
          let newDy = dy + GRAVITY;

          // Handle shooting based on input (e.g., spacebar)
          if (inputHandler.isKeyJustPressed('x')) {
            const bulletSize = 10; // Specify the desired bullet size
            const bullet = createBullet(PIXI, 20, 10);
            // Set the bullet's initial X and Y position to the center of the player
            bullet.x = player.x + player.width / 2 - bullet.width / 2;
            bullet.y = player.y + player.height / 2 - bullet.height / 2;
            // Use the last facing direction to determine bullet velocity
            bullet.vx = lastFacingDirection === 'right' ? BULLET_SPEED : -BULLET_SPEED;
            bullets.push(bullet);
            gameScene.addChild(bullet); // Add the bullet to the gameScene container
          }

          // Update bullet positions and check for collisions
          bullets.forEach((bullet, index) => {
            // Update bullet position
            bullet.x += bullet.vx;

            // Increment the distanceTraveled property of the bullet
            bullet.distanceTraveled += Math.abs(bullet.vx);

            // Check for collisions with platforms or other objects
            for (const platformSprite of platformSprites) {
              if (b.hit(bullet, platformSprite)) {
                // Remove bullet from the stage and the bullets array
                gameScene.removeChild(bullet); // Remove the bullet from the gameScene container
                bullets.splice(index, 1);
                break;
              }
            }

            // Optionally, check for bullet expiration (e.g., distance traveled)
            // and remove expired bullets
            if (bullet.distanceTraveled >= MAX_BULLET_DISTANCE) {
              // Remove bullet from the stage and the bullets array
              gameScene.removeChild(bullet); // Remove the bullet from the gameScene container
              bullets.splice(index, 1);
              return; // Skip the remaining checks for this bullet
            }

          });

          // Check collisions after applying horizontal and vertical movement
          let isOnGround = newY + PLAYER_SIZE >= CANVAS_HEIGHT;

          for (const platformSprite of platformSprites) {
            // Use the hit function from the Bump library to check for collisions
            if (b.hit(player, platformSprite)) {
              // Use rectangleCollision for collision response
              const collision = b.rectangleCollision(player, platformSprite, true);
              if (collision === "bottom" && newDy >= 0) {
                // Player is above the platform
                isOnGround = true;
                dy = 0; // Reset vertical velocity
              }
            }
          }

          // Reset player color to default
          player.tint = PLAYER_COLOR_DEFAULT;

          // Handle horizontal movement based on input
          // Handle horizontal movement based on input
          if (inputHandler.isKeyPressed('ArrowLeft')) {
            newX -= PLAYER_SPEED;
            lastFacingDirection = 'left'; // Update last facing direction
            if (!isOnGround) { // Check if the player is in the air
              player.tint = dy > 0 ? PLAYER_COLOR_FALL_LEFT : PLAYER_COLOR_FALL_LEFT; // Orange if descending, blue if ascending
            } else {
              player.tint = PLAYER_COLOR_LEFT; // Change color to left movement color
            }
          } else if (inputHandler.isKeyPressed('ArrowRight')) {
            newX += PLAYER_SPEED;
            lastFacingDirection = 'right'; // Update last facing direction
            if (!isOnGround) { // Check if the player is in the air
              player.tint = dy > 0 ? PLAYER_COLOR_FALL_RIGHT : PLAYER_COLOR_FALL_RIGHT; // Teal if descending, blue if ascending
            } else {
              player.tint = PLAYER_COLOR_RIGHT; // Change color to right movement color
            }
          } else if (!isOnGround && dy < 0) {
            player.tint = PLAYER_COLOR_JUMP; // Set to jump color if player is jumping straight up
          } else if (!isOnGround && dy > 0) {
            player.tint = PLAYER_COLOR_DESCENT; // Set to descent color if player is falling straight down
          } else if (isOnGround) {
            // Set to default color if player is on the ground and not moving horizontally
            // Use the last facing direction to determine the default color
            if (lastFacingDirection === 'left') {
              player.tint = PLAYER_COLOR_LEFT;
            } else if (lastFacingDirection === 'right') {
              player.tint = PLAYER_COLOR_RIGHT;
            } else {
              player.tint = PLAYER_COLOR_DEFAULT;
            }
          }

          // If the player collides with a platform or the bottom of the game area, prevent further falling
          if (isOnGround) {
            dy = 0; // Reset vertical velocity
          }

          // Handle jump based on input
          if (isOnGround && inputHandler.isKeyJustPressed('z')) {
            dy = -JUMP_HEIGHT;
            // The jump color is already set in the horizontal movement handling section, so no need to set it here
          } else if (dy < 0) {
            // Modify the vertical velocity using JUMP_SPEED
            dy += GRAVITY * JUMP_SPEED;
          } else {
            // Apply gravity during descent or when not jumping
            dy += GRAVITY;
          }

          // Apply gravity during descent or when not jumping
          dy += GRAVITY;

          // Use dy to calculate newY value
          newY = Math.min(player.y + dy, CANVAS_HEIGHT - PLAYER_SIZE);

          // Update player's position
          player.x = newX;
          player.y = newY;

          // Update the game scene position to keep the player centered on the screen
          gameScene.x = -player.x + CANVAS_WIDTH / 2;
          gameScene.y = -player.y + CANVAS_HEIGHT / 2;

          // Constrain the game scene position to keep it within the game area
          gameScene.x = Math.min(Math.max(gameScene.x, -(GAME_WIDTH - CANVAS_WIDTH)), 0);
          gameScene.y = Math.min(Math.max(gameScene.y, -(GAME_HEIGHT - CANVAS_HEIGHT)), 0);

        }; // End game loop logic

        // Start the game loop
        console.log('Starting game loop'); // Add this log statement
        app.ticker.add(gameLoop);

    }).catch(error => {
      console.error('Failed to create player animated sprite:', error);
    });



    // Clean up the PIXI application when the component is unmounted
    return () => {
      app.destroy(true);
    };
  }, []);

  return <div ref={gameContainer} />;
};

export default Game;

playerSpritesheet.json:

{
  "frames": {
    "idle_frame": {
      "frame": {"x": 0, "y": 0, "w": 64, "h": 64},
      "sourceSize": {"w": 64, "h": 64}
    },
    "walk_left_1": {
      "frame": {"x": 64, "y": 0, "w": 64, "h": 64},
      "sourceSize": {"w": 64, "h": 64}
    },
    "walk_left_2": {
      "frame": {"x": 128, "y": 0, "w": 64, "h": 64},
      "sourceSize": {"w": 64, "h": 64}
    },
    "walk_right_1": {
      "frame": {"x": 192, "y": 0, "w": 64, "h": 64},
      "sourceSize": {"w": 64, "h": 64}
    },
    "walk_right_2": {
      "frame": {"x": 256, "y": 0, "w": 64, "h": 64},
      "sourceSize": {"w": 64, "h": 64}
    },
    "jump_right": {
      "frame": {"x": 320, "y": 0, "w": 64, "h": 64},
      "sourceSize": {"w": 64, "h": 64}
    },
    "jump_left": {
      "frame": {"x": 384, "y": 0, "w": 64, "h": 64},
      "sourceSize": {"w": 64, "h": 64}
    },
    "fall_right": {
      "frame": {"x": 448, "y": 0, "w": 64, "h": 64},
      "sourceSize": {"w": 64, "h": 64}
    },
    "fall_left": {
      "frame": {"x": 512, "y": 0, "w": 64, "h": 64},
      "sourceSize": {"w": 64, "h": 64}
    },
    "shoot_right": {
      "frame": {"x": 576, "y": 0, "w": 64, "h": 64},
      "sourceSize": {"w": 64, "h": 64}
    },
    "shoot_left": {
      "frame": {"x": 640, "y": 0, "w": 64, "h": 64},
      "sourceSize": {"w": 64, "h": 64}
    }
  },
  "meta": {
    "image": "../assets/images/playerSpritesheet.png",
    "size": {"w": 704, "h": 64},
    "scale": "1"
  }
}

Assert types when calling javascript compiled from typescript

I am using a library, compiled from Typescript to Javascript in my Javascript project.

The method signatures in the Typescript API use typed method arguments.

This type information is lost in the compiled Javascript artifact.

I am aware, that types are a core feature of Typescript. Is it possible, to ensure type safety when calling the Javascript library from a Javascript project? For example using types.d.ts and a static analysis tool?