Vuforia query to fetch id of matching target

Creating a simple web “application” and integrating it with Vuforia using the web api. I managed to add targets to cloud dataset. But I am struggling to create the right query where I send an image from my laptop and get the id of its matching target in the cloud dataset.

Anyone with more experience in this who can point me at the naïve flaw?

Here are the 3 files:

1) main.js:

document.getElementById('uploadForm').addEventListener('submit', function(event) {
    event.preventDefault();

    let formData = new FormData();
    let imageFile = document.getElementById('imageUpload').files[0];
    formData.append('image', imageFile);

    fetch('query_vuforia.php', {
        method: 'POST',
        body: formData
    })
    .then(response => response.text())
    .then(data => {
        const jsonData = JSON.parse(data);
        console.log('Vuforia response:', jsonData);
        if (jsonData.error) {
            document.getElementById('result').innerHTML = 'Error: ' + jsonData.error;
            console.error('HTTP Response Code:', jsonData.httpCode || 'Unknown error code');
        } else {
            document.getElementById('result').innerHTML = JSON.stringify(jsonData, null, 2);
        }
    })
    .catch(error => {
        console.error('Error:', error);
        document.getElementById('result').innerHTML = 'Error: ' + error.message;
    });
});


2) query_vuforia.php

<?php
require_once 'SignatureBuilder.php';

// Authentication keys
$access_key = '*******************';
$secret_key = '**********************';

// URL for the Vuforia Query API
$url = "https://cloudreco.vuforia.com";
$requestPath = "/v1/query";

if ($_FILES['image']['error'] === UPLOAD_ERR_OK && is_uploaded_file($_FILES['image']['tmp_name'])) {
    $image = new CURLFile($_FILES['image']['tmp_name'], 'image/jpeg', 'image.jpg');

    // Initialize cURL session
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url . $requestPath);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, ['image' => $image]);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    // Create the date and signature
    $date = new DateTime('now', new DateTimeZone('GMT'));
    $dateString = $date->format('D, d M Y H:i:s') . ' GMT';
    $sb = new SignatureBuilder();
    $signature = $sb->tmsSignature($requestPath, 'POST', $image, 'multipart/form-data', $date, $secret_key);
    
    // Set headers for the query request
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Authorization: VWS ' . $access_key . ':' . $signature,
        'Date: ' . $dateString
    ]);

    // Execute the query request
    $response = curl_exec($ch);

    // Check for cURL errors and process the response
    if (curl_errno($ch)) {
        echo json_encode(['error' => 'cURL error: ' . curl_error($ch)]);
    } else {
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $responseData = json_decode($response, true);
        if ($httpCode === 200) {
            // Process and output the response
            echo json_encode($responseData);
        } else {
            // Include the httpCode in the JSON response for the JS to use
            echo json_encode(['error' => 'Error querying target.', 'httpCode' => $httpCode]);
        }
    }

    // Close cURL session
    curl_close($ch);
} else {
    echo json_encode(['error' => 'Error: No image uploaded or file error.']);
}
?>


3) SignatureBuilder.php

<?php

class SignatureBuilder {

    public function tmsSignature($requestPath, $method, $contentType, $date, $secret_key) {
        // For multipart/form-data, the content is an empty string
        $content = "";

        // The body's MD5 hash is not needed for multipart/form-data, an empty string is used
        $hexDigest = md5($content, false);

        // Construct the string to sign.
        $toDigest = $method . "n" . $hexDigest . "n" . $contentType . "n" . $date->format("D, d M Y H:i:s") . " GMT" . "n" . $requestPath;

        // SHA1 hash, transformed from hexadecimal to Base64.
        $shaHashed = base64_encode(pack('H*', hash_hmac("sha1", $toDigest, $secret_key)));

        return $shaHashed;
    }
}
?>



I tried to apply what is explained in the documentation link below, but it didn’t work:

https://developer.vuforia.com/library/web-api/vuforia-query-web-api

What I’m expecting is that once I select an image, post it to Vuforia, I get the right message from vuforia (including whether there is a match and what is the target id of the matching marker in the cloud dataset).

How to run JS code outside Mapbox js code to change layer color

I want to change the color of circle, when I call the function from inside the mapbox js it work, but when I run the function from outside the mopbox js it does not work.

map.setPaintProperty(
  "unclustered-point", 
  "circle-color", 
  ["match", ["get", "id"], data, "#FFFF00", ["get", "color"]]
);

I did try something out like to see if loading the layers would help but no luck.

map.on('load', 'unclustered-point', () => {
    map.setPaintProperty(
        "unclustered-point", 
        "circle-color", 
        ["match", ["get", "id"], data, "#FFFF00", ["get", "color"]]
    );
});

Firebase callable function call from web app

I have initialized a firebase app in my web page and defined a callable function as follows :

var config = {
    apiKey: "...xyz...",
    authDomain: "[project-id].firebaseapp.com",
    databaseURL: "https://[project-id].firebaseio.com",
    storageBucket: "[project-id].appspot.com"
};
const app = firebase.initializeApp(config);
const mySimpleCallableFunction = firebase.functions(app).httpsCallable('mySimpleCallableFunction');

When the user clicks on a button, i call the function:

mySimpleCallableFunction({ param1: '...xyz...' })
    .then((result) => {
        console.log(result);
    });

I am getting a CORS error when trying to execute the function. I don’t think CORS is the real issue here though as it looks to me like the URL for the callable function is NOT put together correctly, it has undefined where the project-id should be.

Access to fetch at
‘https://us-central1-undefined.cloudfunctions.net/mySimpleCallableFunction’
from origin …

Any ideas on how to fix this?

ckeditor5 – How to set text to bold and centered by default

I’m using ckeditor5 and I’m trying to set the editor by default to be bold and center.
So that the user starts writing, the text will be bolded and centered.

I saw similar questions asked, but none of the answers worked as expected,
I tried to use text-align: center on the editor element, and also on the parent element, but it didn’t work (I also used !important)

This is the HTML code of the editor

<div style="margin-top: 2rem; text-align: center !important; font-weight: bold !important">
    <textarea id="editor" placeholder="title" style="text-align: center !important; font-weight: bold !important"></textarea>
</div>

This is the javascript code that create the editor

const watchdog = new CKSource.EditorWatchdog();

window.watchdog = watchdog;

watchdog.create(document.querySelector('#editor'), {
        // Editor configuration.
    })
    .catch(handleSampleError);

What can I do?

How to convert canvas animations from vanilla js into a react component

I am struggling to convert a canvas animation from vanilla js to react component. I tried to export the js from a separate file. But it did not work. Futerh=more I tried to use useref and use state as advised from a medium article

The link is:
Here is the code:

let canvas, ctx, w, h, snows, snows2;

function init() {
    canvas = document.querySelector("#canvas");
    ctx = canvas.getContext("2d");

    resizeReset();
    animationLoop();
}

function resizeReset() {
    w = canvas.width = window.innerWidth;
    h = canvas.height = window.innerHeight;

    snows = [];
    for (let i = 0; i < 500; i++) {
        snows.push(new Snow());
    }
    snows2 = [];
    for (let i = 0; i < 500; i++) {
        snows2.push(new Snow2());
    }
}

function animationLoop() {
    ctx.clearRect(0, 0, w, h);
    drawScene();
    requestAnimationFrame(animationLoop);
}

function drawScene() {
    for (let i = 0; i < snows.length; i++) {
        snows[i].update();
        snows[i].draw();
    }
    for (let i = 0; i < snows2.length; i++) {
        snows2[i].update();
        snows2[i].draw();
    }
}

function getRandomInt(min, max) {
    return Math.round(Math.random() * (max - min)) + min;
}

class Snow {
    constructor() {
        this.reset();
        this.rgb = "219,172,52";
    }
    reset() {
        this.x = getRandomInt(0, w);
        this.xc = ((this.x - (w / 2)) / (w / 2)) / 2;
        this.y = getRandomInt(-(h * 0.3), h);
        this.yc = getRandomInt(10, 15) / 10;
        this.size = getRandomInt(10, 20) / 10;
        this.a = getRandomInt(-10, 0) / 10;
        this.ac = getRandomInt(3, 5) / 100;
    }
    draw() {
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
        ctx.fillStyle = `rgba(${this.rgb}, ${this.a})`;
        ctx.strokeStyle = `rgba(${this.rgb}, ${this.a})`;
        ctx.fill();
        ctx.stroke();
        ctx.closePath();
    }
    update() {
        this.x += this.xc;
        this.y += this.yc;
        this.a += this.ac;
        if (this.a > 2) {
            this.ac *= -1;
        } else if (this.a < 0 && this.ac < 0) {
            this.reset();
        }
    }
}

class Snow2 {
    constructor() {
        this.reset();
        this.rgb = "256,256,256";
    }
    reset() {
        this.x = getRandomInt(0, w);
        this.y = getRandomInt(0, h);
        this.size = getRandomInt(0, 5) / 10;
        this.a = getRandomInt(-10, 0) / 10;
        this.ac = 0.01;
    }
    draw() {
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
        ctx.fillStyle = `rgba(${this.rgb}, ${this.a})`;
        ctx.strokeStyle = `rgba(${this.rgb}, ${this.a})`;
        ctx.fill();
        ctx.stroke();
        ctx.closePath();
    }
    update() {
        this.y -= 0.1;
        this.a += this.ac;
        if (this.a > 1.5) {
            this.ac *= -1;
        } else if (this.a < 0 && this.ac < 0) {
            this.reset();
        }
    }
}

window.addEventListener("DOMContentLoaded", init);
window.addEventListener("resize", resizeReset);re

I will be really thankful to anyone who can help me. Please

I tried to put it in a separate file and tried to export. I tried to dabble with useref and usestate but could not make out

Voice-chat Ai detector that detects racism on sites like Omegle? Is it possible to create [closed]

Whenever i get on ome.tv and monkey which are sites like omegle I always get called racial slurs and it made me wonder. Is it possible to moderate voice chat on websites like these? For example on Omegle , if somebody calls you the N word is it possible for the AI voice detector to detect the n word being said and being able to ban them for that?

My browser returns me to the previous page when i click on an link

I have a website (with html, css, js, tailwind css) and I implemented the navigation (menus) using links, which menu items (links) other than a menu item (link) link to a page with Different serach query value as below

<ul class="basis-2/5 hidden sm:flex sm:basis-1/2 md:basis-2/5 justify-evenly items-center text-base">
                <li class="relative font-bold text-gray-500 dark:text-gray-400 after:absolute after:left-1/2 after:-bottom-2 after:-translate-1/2 hover:after:inline-block hover:text-secondary dark:hover:text-white transition-colors duration-200 hover:texet-secondary after:w-1 after:h-1 after:rounded-md after:bg-secondary dark:after:bg-gray-100 after:hidden">
                    <a href="./index.html">Home</a>
                </li>
                <li class="menLiElem relative font-bold text-gray-500 dark:text-gray-400 after:absolute after:left-1/2 after:-bottom-2 after:-translate-1/2 hover:after:inline-block hover:text-secondary dark:hover:text-white transition-colors duration-200 after:w-1 after:h-1 after:rounded-md after:bg-secondary dark:after:bg-gray-100 after:hidden">
                    <a href="./products.html?t=men">Men</a>
                </li>
                <li class="womenLiElem relative font-bold text-gray-500 dark:text-gray-400 after:absolute after:left-1/2 after:-bottom-2 after:-translate-1/2 hover:after:inline-block hover:text-secondary dark:hover:text-white transition-colors duration-200 after:w-1 after:h-1 after:rounded-md after:bg-secondary dark:after:bg-gray-100 after:hidden">
                    <a href="./products.html?t=women">Women</a>
                </li>
                <li class="kidsLiElem relative font-bold text-gray-500 dark:text-gray-400 after:absolute after:left-1/2 after:-bottom-2 after:-translate-1/2 hover:after:inline-block hover:text-secondary dark:hover:text-white transition-colors duration-200 after:w-1 after:h-1 after:rounded-md after:bg-secondary dark:after:bg-gray-100 after:hidden">
                    <a href="./products.html?t=kids">Kids</a>
                </li>
                <li class="allLiElem ">
                    <a href="./products.html?t=all">Collections</a>
                </li>
            </ul>

And in the products.html page, I have come from
location.search
I got the value sent and according to it, I give active style to the selected menu item and display the product to the user as below

 let locationElems = new URLSearchParams(location.search)
    let productType = !locationElems.size ? 'all' : 
                    ['all' , 'men' , 'women' , 'kids'].includes(locationElems.get('t').toLowerCase()) ? locationElems.get('t').toLowerCase() : null


    groupBtn.querySelector('span').innerHTML = productType || 'All'

    let menuElems = null
    if(productType && productType != 'all'){
        menuElems = document.querySelectorAll(`.${productType.toLowerCase()}LiElem`)
    } else {
        menuElems = document.querySelectorAll('.allLiElem')
    }

    menuElems.forEach(menuElem => menuElem.classList.add('active'))

and i filter products As follows

allProducts = productType == 'all' ? [...products] : products.filter(product => product.productCategory.toLowerCase() == productType)
        let filteredProducts = allProducts

Now all the links work, but when I click on the link and the collections menu item, it returns me to the previous history page.
What should I do to solve this problem?

I don’t think there is a problem, that’s why I tried it with a number of browsers and it gave the same result as before and I have no idea how can I solve this problem?

Socket.io Promise.all unexpected results

This is my socket.io server code and the socket.emit() function works as i am getting back the expected result, but the Promise.all function ruins the output. Below is the log of this application

socket.on('hh:broadcast', (props, cb) => {
        const session = sockets.get(socket);
        if (!session) return;
        const [room, that] = session;
        const collaborators = sessions.get(room)!;

        Promise.all<ArrayElement<NonNullable<Parameters<typeof cb>['0']>>>(collaborators
            .filter(([, other]) => other !== that)
            .map(([sock, other]) => sock
                .emitWithAck('hh:data', { id: that, ...props })
                .then(res => {
                    log.info("received", other, res);
                    return { id: other, ...res };
                }))
        ).then(res => {
            log.warn("Promise.all:", JSON.stringify(res))
            cb(res);
        });
   });

the log shows the result of the Promise.all, but it is not correct (only contains the emit of one client, not the rest, they are simply empty arrays) Why is that? I am getting back the correct result inside the promises, but the Promise.all can’t merge these results into an array?

19:43:28.431 [WebSocket] received gDmNz9Ih2WWw {data: {data: [49, 237, 191, 23, 68, 120, 57, 163, 65, 57, 62, 200, 19, 155, 179, 23, 183, 242, 236, 97, 164, 99], type: "Buffer"}}
19:43:28.431 [WebSocket] received mX6SfA2F0MsD {data: {data: [49, 229, 183, 22, 72, 120, 202, 117, 249, 93, 17, 39, 226, 13, 101, 160, 208, 243, 76, 82, 95, 116], type: "Buffer"}}
19:43:28.431 [WARNING WebSocket] Promise.all: [{"id":"mX6SfA2F0MsD","data":{"type":"Buffer","data":[49,229,183,22,72,120,202,117,249,93,17,39,226,13,101,160,208,243,76,82,95,116]}},{"id":"gDmNz9Ih2WWw","data":{"type":"Buffer","data":[]}}]

Js Array gives null

Why Array gives null outside script onclick event in htm5? The others variables works correctly.

<!DOCTYPE html>
<html>
<head>
  <title>Array</title>
  <script>
    var list = new Array("andrea", "matteo", "marco");
    var x = "andrea";
  </script>
</head>
<body>
  <input type="button" value="click" onclick="alert(list[0]);">
</body>
</html>

How do I ensure that this Vara lib animation loops correctly without extending the page?

I’m very much not an expert to JS and I was wondering how I can make sure this animation restarts at “video” again after “leads”.

I used the codepen from Adil Ahmed to create a version for my own, because I’m not really an expert at JavaScript. What happens currently with this code is that, when the animation restart, it extends the page. I’ve already tried destroying the session first but alas, I’m not good enough to solve this problem on my own.

This is my code:

var fontSize = 78;

function startVaraAnimation() {
  if (window.screen.width < 700) 
    fontSize = 38;
  else if (window.screen.width < 1200)
    fontSize = 58;

  // Reset opacity before starting the animation
  document.getElementById("handtext").style.opacity = 1;

  var vara = new Vara(
    "#handtext",
    "https://rawcdn.githack.com/akzhy/Vara/ed6ab92fdf196596266ae76867c415fa659eb348/fonts/Satisfy/SatisfySL.json",
    [
      {
        text: "video",
        y: 10,
        fromCurrentPosition: { y: false },
        duration: 1000
      },
      {
        text: "branding",
        y: 10,
        fromCurrentPosition: { y: false },
        delay: 2000,
        duration: 2000
      },
      {
        text: "leads",
        y: 10,
        fromCurrentPosition: { y: false },
        delay: 2000,
        duration: 1000
      },
    ],
    {
      strokeWidth: 2,
      color: "#FF8A1F",
      fontSize: fontSize,
      textAlign: "center" 
    }
  );

  vara.ready(function() {
    var erase = true;
    vara.animationEnd(function(i, o) {
      if (i == "no_erase") erase = false;
      if (erase) {
        o.container.style.transition = "opacity 1s 1s";
        o.container.style.opacity = 0;
      }
    });
  });
}

// Run the animation initially
startVaraAnimation();

// Set up an interval to reset the text animation
setInterval(function() {
  // Reset opacity before starting the animation
  document.getElementById("handtext").style.opacity = 1;

  // Start the animation
  startVaraAnimation();
}, 10000); // Adjust the interval as needed

HTML:

<div class="handwritten">
  <div id="handtext"></div>

CSS:

.handwritten {
  overflow: hidden;
  display: inline-block; /* or display: block; */
}

#handtext {
  overflow: hidden;
}

@keyframes new
{
  0%
  {
    transform:scaleX(1);
  }
  50%
  {
    transform:scaleX(.95);
  }
  100%
  {
    transform:scaleX(1);
  }
}

Vue app.use() doesn’t accept my router as a parameter

I am making a new project using Django and Vue 3 (with pinia). I am trying to set up vue router (the lastest version) and I found these instructions in the vue router website https://router.vuejs.org/guide/

// 1. Define route components.
// These can be imported from other files
const Home = { template: '<div>Home</div>' }
const About = { template: '<div>About</div>' }

// 2. Define some routes
// Each route should map to a component.
// We'll talk about nested routes later.
const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About },
]

// 3. Create the router instance and pass the `routes` option
// You can pass in additional options here, but let's
// keep it simple for now.
const router = VueRouter.createRouter({
  // 4. Provide the history implementation to use. We are using the hash history for simplicity here.
  history: VueRouter.createWebHashHistory(),
  routes, // short for `routes: routes`
})

// 5. Create and mount the root instance.
const app = Vue.createApp({})
// Make sure to _use_ the router instance to make the
// whole app router-aware.
app.use(router)

app.mount('#app')

// Now the app has started!

I did something similar:

import './assets/main.css'

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import router from "./router";
import App from './App.vue'

import { createRouter, createWebHistory } from "vue-router";

const routes = [
    { path: "/", component: () => import("/src/pages/Index.vue") }
]

const router = createRouter({
    history: createWebHistory(),
    routes
})

const app = createApp(App)
app.use(createPinia())
app.use(router)

app.mount('#app')

My IDE (using PyCharm) says that router is not an acceptable parameter for app.use(). The exact message is:

Argument type Router is not assignable to parameter type Plugin<unknown[]> ...   Type Router is not assignable to type (((app: App, ...options: unknown[]) => any) & {install?: PluginInstallFunction<unknown[]>}) | {install: PluginInstallFunction<unknown[]>}     Type (app: App) => void is not assignable to type PluginInstallFunction<unknown[]> 

I don’t get any errors when I run the servers but it doesn’t show my index page and always stays on App.vue.

What am I doing wrong?

Change the font size of the entire HTML by clicking a button. (radiobutton)

I have been trying for a while to change the font size of the whole HTML using JS, which can be done at the click of a button. But it does not work.

HTML

            <!-- Font Size -->
            <div class="settings-element" style="text-align: right">
                    <h3 style="text-align: left;">Font-Size</h3>
                <div class="radio-input-font-size">
                    <label>
                    <input type="radio" id="value-1" name="value-radio" value="value-1">
                    <span>Standard</span>
                    </label>
                    <label>
                      <input type="radio" id="value-2" name="value-radio" value="value-2">
                    <span>Smaller</span>
                    </label>
                    <label>
                      <input type="radio" id="value-3" name="value-radio" value="value-3">
                    <span>Larger</span>
                    </label>
                    <span class="selection"></span>
                </div>
            </div>

It should reduce all text in the HTML by 5px at the touch of a button. (font-size).

Axios “Network Error” when making a POST request from React to Node.js server

Description

I’m encountering an issue with Axios when attempting to make a POST request from my React app to a Node.js server. The error message I’m receiving is “Network Error.” I’ve checked the server, and it seems to be running fine. Here are the details of my setup:

// allowance.js

import React, { useState, useEffect } from 'react';
import { useSession } from './session';
import axios from 'axios';

function MonthlyAllowance() {
  const { session } = useSession();
  const [description, setDescription] = useState('');
  const [ticketData, setTicketData] = useState(null);
  const [result, setResult] = useState('');
  const [notes, setNotes] = useState('');

  useEffect(() => {
    document.title = "Monthly Allowance | Solo Parent";
    window.scrollTo(0, 0);
  }, []);

  const handleFormSubmitAllowance = async (e) => {
    e.preventDefault();

    try {
      const response = await axios.post('http://localhost:3001/api/create-user-ticket', {
        userId: session.userId,
        type: 'Monthly Allowance',
        description: description,
        clientName: session.name,
      });

      console.log('Ticket submission successful:', response.data);
      setTicketData(response.data); // Save the ticket data in the state

      // You can add logic to handle successful submission, such as showing a success message or redirecting the user.
    } catch (error) {
      console.error('Error submitting ticket:', error);

      // You can add logic to handle the error, such as displaying an error message to the user.
    }
  };

  return (
    <>
      <form onSubmit={handleFormSubmitAllowance} className='ticketing-modal'>
        <div className='ticketing'>
          <fieldset>
            <legend>Ticketing Monthly Allowance</legend>
            <div>
              <label htmlFor='description'>Description:</label>
              <input
                type='text'
                id='description'
                value={description}
                onChange={(e) => setDescription(e.target.value)}
                placeholder='Description'
              />
            </div>
            <div>
              <label htmlFor='result'>Result:</label>
              <input
                type='text'
                id='result'
                value={result}
                onChange={(e) => setResult(e.target.value)}
                placeholder='Result'
              />
            </div>
            <div>
              <label htmlFor='notes'>Notes:</label>
              <textarea
                id='notes'
                value={notes}
                onChange={(e) => setNotes(e.target.value)}
                placeholder='Notes'
              />
            </div>
          </fieldset>
          <button type='submit'>Submit</button>
        </div>
      </form>

      {/* Display the created ticket data */}
      {ticketData && (
        <div className='ticketing'>
          <fieldset>
            <legend>Created Ticket Details</legend>
            <div>
              <strong>Ticket ID: <span>{ticketData.ticketId}</span></strong>
              <strong>Type: <span>{ticketData.type}</span></strong>
              <strong>Status: <span>{ticketData.status}</span></strong>
              <strong>Description:</strong>
              <p className='result'>{ticketData.description}</p>
              <strong>Result:</strong>
              <p className='result'>{ticketData.result}</p>
              <strong>Notes:</strong>
              <p className='result'>{ticketData.notes}</p>
              {/* Add other ticket data fields as needed */}
            </div>
          </fieldset>
        </div>
      )}
    </>
  );
}

export default MonthlyAllowance;
// index.js

const express = require("express");
const cors = require('cors');
const path = require('path');
const bodyParser = require("body-parser");
const {
  createSoloParentAccount,
  readSoloParentDataById,
  deleteSoloParentData,
  updateSoloParentData,
  readAllSoloParentData,
  userLogin,
  createUserTickets
} = require("./api");
const multer = require("multer");
const pino = require("pino");
const expressPino = require("express-pino-logger");

const logger = pino();
const expressLogger = expressPino({ logger });

// Define storage for multer on disk
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    // Set the destination folder for uploaded files
    cb(null, path.join(__dirname, "uploads")); // Adjust the folder path as needed
  },
  filename: function (req, file, cb) {
    // Set the filename for uploaded files
    cb(
      null,
      file.fieldname + "-" + Date.now() + path.extname(file.originalname)
    );
  },
});

const { Pool } = require("pg");
const upload = multer({ storage: storage });

const app = express();
app.use(cors());
app.use(expressLogger);
app.use(express.static(path.join(__dirname, "ui")));
const PORT = 3001;
app.use(bodyParser.json());

//Index Page
app.get("/", (req, res) => {
  res.send("Force sent");
});

// Endpoint to login account
app.post(
  "/api/login",
  userLogin
);

// Endpoint to create user tickets
app.post(
  "/api/create-user-ticket", 
  createUserTickets
);


// app.use("/api", (req, res, next) => {
//   //middleware
// });

// Endpoint to create a user account
app.post(
  "/api/create-solo-parent-account",

  createSoloParentAccount
);

//Note: Finalize ko pa yung upload file na field. di ko pa alam nangyayari dito haha
// upload.fields([
//   { name: "voters", maxCount: 1 },
//   { name: "barangayCert", maxCount: 1 },
//   { name: "certOfEmployment", maxCount: 1 },
//   { name: "paySlip", maxCount: 1 },
//   { name: "nonFillingtr", maxCount: 1 },
//   { name: "businessPermit", maxCount: 1 },
//   { name: "affSoloParent", maxCount: 5 },
//   { name: "pbcc", maxCount: 1 },
//   { name: "pwdid", maxCount: 1 },
//   { name: "deathcert", maxCount: 1 },
//   { name: "picture", maxCount: 1 },
// ]),

//Endpoint for getting user data by ID
app.get("/api/read-solo-parent-account/:userId", async (req, res, next) => {
  const userId = req.params.userId;

  try {
    const userData = await readSoloParentDataById(userId);

    if (!userData) {
      res.status(404).send("User not found");
      return;
    }

    res.json(userData);
  } catch (error) {
    next(error);
  }
});

// Endpoint to read all user data
app.get("/api/read-all-solo-parent-data", async (req, res, next) => {
  try {
    const allData = await readAllSoloParentData();
    res.json(allData);
  } catch (error) {
    next(error);
  }
});

// Endpoint to delete user data by ID
app.delete("/api/delete-solo-parent-account/:userId", async (req, res) => {
  const userId = req.params.userId;

  try {
    const deleted = await deleteSoloParentData(userId);
    if (!deleted) {
      return res.status(404).json({ error: "User not found" });
    }

    res.json({ message: "User data deleted successfully" });
  } catch (error) {
    console.error("Error deleting user data:", error);
    res.status(500).send("Internal Server Error");
  }
});

// Endpoint to update user data
app.put("/api/update-solo-parent-account/:userId", async (req, res, next) => {
  const userId = req.params.userId;
  const updatedData = req.body; // Updated data should be sent in the request body

  try {
    const success = await updateSoloParentData(userId, updatedData);
    if (success) {
      res.sendStatus(200); // Send a success response
    } else {
      res.status(500).send("Failed to update user data"); // Send an error response
    }
  } catch (error) {
    next(error);
  }
});

app.listen(PORT, () => {
  logger.info(`Server is running on http://localhost:${PORT}`);
  console.log(`Server is running at http://localhost:${PORT}`);
});
// api.js

const jsforce = require("jsforce");
require("dotenv").config();
const { SF_LOGIN_URL, SF_USERNAME, SF_PASSWORD, SF_TOKEN } = process.env;

const conn = new jsforce.Connection({
  loginUrl: SF_LOGIN_URL,
});

conn.login(SF_USERNAME, SF_PASSWORD + SF_TOKEN, (err, userInfo) => {
  if (err) {
    console.error(err);
  } else {
    console.log("User ID: " + userInfo.id);
    console.log("Org ID: " + userInfo.organizationId);
  }
});

async function createSoloParentAccount(req, res, next) {
  const { personalInfo, familyComposition } = req.body;
  const fileDataArray = req.files || [];

  async function processFileUploads(conn, soloParentFormId, fileDataArray) {
    if (
      fileDataArray &&
      typeof fileDataArray === "object" &&
      Object.keys(fileDataArray).length > 0
    ) {
      // Map each fileData to a promise that uploads the file
      const fileUploadPromises = Object.keys(fileDataArray).map(
        async (fileType) => {
          const fileData = fileDataArray[fileType];

          // Assuming fileData.data is a Buffer
          const fileObjectData = {
            OwnerId: "0055g00000J9SHLAA3",
            Title: fileData.name,
            PathOnClient: fileData.name,
            VersionData: fileData.data.toString("base64"),
            // ... (other fields specific to this file upload)
          };

          console.log("File Data Array:", fileObjectData);

          try {
            // Upload the file
            const fileUploadResp = await conn
              .sobject("ContentVersion")
              .create(fileObjectData);

            // Check if the file upload failed
            if (!fileUploadResp.success) {
              console.error(
                `Failed to process file upload for ${fileData.name}`
              );
              console.error(fileUploadResp);
              throw new Error("Failed to process file upload");
            }

            console.log(`File ${fileData.name} uploaded successfully`);

            // Retrieve the ContentDocumentId associated with the ContentVersion
            const contentDocumentId = (
              await conn
                .sobject("ContentVersion")
                .retrieve(fileUploadResp.id, ["ContentDocumentId"])
            ).ContentDocumentId;

            // Link the uploaded file to the Solo Parent Application Form
            const contentDocumentLinkResp = await conn
              .sobject("ContentDocumentLink")
              .create({
                ContentDocumentId: contentDocumentId,
                LinkedEntityId: soloParentFormId,
                // ... (other fields specific to ContentDocumentLink)
              });

            // Rest of your code

            // Check if the ContentDocumentLink failed
            if (!contentDocumentLinkResp.success) {
              console.error(
                `Failed to link file to the record for ${fileData.name}`
              );
              console.error(contentDocumentLinkResp);
              // Rollback: Delete the associated ContentVersion and ContentDocumentLink
              await conn.sobject("ContentVersion").destroy(fileUploadResp.id);
              await conn
                .sobject("ContentDocumentLink")
                .destroy(contentDocumentLinkResp.id);
              throw new Error("Failed to link file to the record");
            }

            console.log(
              `File ${fileData.name} linked to the record successfully`
            );
          } catch (error) {
            console.error(`Error processing file ${fileData.name}:`, error);
            throw error; // Re-throw the error to stop further processing
          }
        }
      );

      try {
        // Wait for all file upload operations to complete
        await Promise.all(fileUploadPromises);

        // Continue with the rest of your logic
        // ...

        console.log("File uploads and linking successful");
      } catch (error) {
        // Handle errors during file upload and linking
        console.error("Error during file upload and linking:", error);
        throw new Error("Failed to upload and link files");
      }
    }
  }

  try {
    // Start Basic Information
    // Construct the data for creating a user account
    const userAccountData = {
      Surname__c: personalInfo.surName,
      Given_Name__c: personalInfo.givenName,
      Middle_Name__c: personalInfo.middleName,
      Extension__c: personalInfo.extension,
      Civil_Status__c: personalInfo.civilStatus,
      Sex__c: personalInfo.sex,
      Age__c: personalInfo.age,
      // Date_of_Birth__c: personalInfo.dateOfBirth,
      Email__c: personalInfo.email,
      birthday_string__c: personalInfo.dateOfBirthTwo,
      Place_of_Birth__c: personalInfo.placeOfBirth,
      Religion__c: personalInfo.religion,
      Mobile_Number__c: personalInfo.mobileNumber,
      Identification_Card_Number__c: "00",
      Identification_Card_Type__c: personalInfo.idCardType,
      Landline_Number__c: personalInfo.landlineNumber,
      Present_Address__c: personalInfo.presentAddress,
      Highest_Educational_Attainment__c: personalInfo.educationalAttainment,
      Profession__c: personalInfo.profession,
      Occupation__c: personalInfo.occupation,
      Monthly_Income__c: personalInfo.monthlyIncome,
      Name_of_Employer__c: personalInfo.nameOfEmployer,
      Contact_Number_Employer__c: personalInfo.contactNumberEmployer,
      Employer_Address__c: personalInfo.employerAddress,
      Contact_Person__c: personalInfo.contactPerson,
      Contact_Number_Contact_Person__c: personalInfo.contactNumber,
      // Reasons_Circumstances__c: personalInfo.reasonsCircumstances,
    };

    // const userAccountData = {
    //   Surname__c: "glend",
    //   Identification_Card_Number__c: "00",
    // };

    const userAccountResp = await conn
      .sobject("Solo_Parent_Application_Form__c")
      .create(userAccountData);

    // Check if the user account creation was successful
    if (!userAccountResp.success) {
      req.log.error("Failed to create user account");
      req.log.error(userAccountResp);
      res.status(500).send("Failed to create user account");
      return;
    }

    //end Basic Information

    //call user id for the Relationship between the user, family composition and requirements
    const soloParentFormId = userAccountResp.id;
    const soloParentAccountId = userAccountResp.OwnerId;
    // console.log(familyComposition);
    // // Start Fam Composition
    // const familyMembersData = familyComposition.map((familyMember) => ({
    //   Solo_Parent_Application_Form__c: soloParentFormId, // Use the ID of the master record
    //   Name: familyMember.name,
    //   Age__c: familyMember.age,
    //   Sex__c: familyMember.sex,
    //   Relationship__c: familyMember.relationShip,
    //   Highest_Educational_Attainment__c: familyMember.educationalattainment,
    //   Occupation__c: familyMember.occupation,
    //   Monthly_Income__c: familyMember.monthlyIncome,
    // }));

    // const familyMembersRespArray = await Promise.all(
    //   familyMembersData.map((familyMemberData) =>
    //     conn.sobject("Family_Member__c").create(familyMemberData)
    //   )
    // );

    // // Check if any of the family members failed to be created
    // if (familyMembersRespArray.some((resp) => !resp.success)) {
    //   // Rollback: Delete the user account if family member creation fails
    //   await conn
    //     .sobject("Solo_Parent_Application_Form__c")
    //     .destroy([soloParentFormId]);
    //   res.status(500).send("Failed to add family members");
    //   return;
    // }

    //End Fam Composition

    // Step 3: Process the uploaded PDF files

    // Wait until the form is created, then get the OwnerId
    const soloParentFormDetails = await conn
      .sobject("Solo_Parent_Application_Form__c")
      .retrieve(soloParentFormId, ["OwnerId"]);

    // Trigger the file upload function with the generated OwnerId
    await processFileUploads(conn, soloParentFormId, fileDataArray);
    // ... the rest of your logic

    req.log.info(
      "User account, family composition, and uploaded PDF files created successfully"
    );
    res.sendStatus(200);
  } catch (e) {
    next(e);
  }
}

async function readSoloParentDataById(userId) {
  try {
    const query = `SELECT 
      Surname__c, Given_Name__c, Middle_Name__c, Extension__c, Civil_Status__c,
      Sex__c, Age__c, Date_of_Birth__c, birthday_string__c, Place_of_Birth__c, Religion__c,
      Mobile_Number__c, Landline_Number__c, Present_Address__c,
      Highest_Educational_Attainment__c, Profession__c, Occupation__c,
      Monthly_Income__c, Name_of_Employer__c, Contact_Number_Employer__c,
      Employer_Address__c, Contact_Number_Contact_Person__c
      FROM Solo_Parent_Application_Form__c WHERE Id = '${userId}' LIMIT 1`;

    // Execute the query
    const result = await conn.query(query);

    // Check if any records were found
    if (result.totalSize === 0) {
      return null; // No records found
    }

    // Extract the first record
    const record = result.records[0];

    // Return the record as JSON
    return {
      ...record,
    };
  } catch (error) {
    console.error("Error reading data from Salesforce:", error);
    throw error; // Re-throw the error to be handled elsewhere if needed
  }
}

//Display all account
async function readAllSoloParentData() {
  try {
    const query = `SELECT Surname__c, Given_Name__c, Middle_Name__c, Extension__c, Civil_Status__c,
    Sex__c, Age__c, Date_of_Birth__c, Place_of_Birth__c, Religion__c,
    Mobile_Number__c, Landline_Number__c, Present_Address__c,
    Highest_Educational_Attainment__c, Profession__c, Occupation__c,
    Monthly_Income__c, Name_of_Employer__c, Contact_Number_Employer__c,
    Employer_Address__c, Contact_Number_Contact_Person__c FROM Solo_Parent_Application_Form__c LIMIT 10`;

    // Execute the query
    const result = await conn.query(query);

    // Return the records as JSON
    return result.records;
  } catch (error) {
    console.error("Error reading data from Salesforce:", error);
    throw error; // Re-throw the error to be handled elsewhere if needed
  }
}

async function deleteSoloParentData(userId) {
  try {
    // Use the destroy method to delete the record with the specified ID
    const deletedRecords = await conn
      .sobject("Solo_Parent_Application_Form__c")
      .destroy([userId]);

    // Check if the deletion was successful
    if (deletedRecords.length > 0 && deletedRecords[0].success) {
      // Delete associated ContentDocumentLinks and ContentVersions
      const contentDocumentLinks = await conn
        .sobject("ContentDocumentLink")
        .select("ContentDocumentId")
        .where({ LinkedEntityId: userId })
        .execute();

      const contentDocumentIds = contentDocumentLinks.map(
        (link) => link.ContentDocumentId
      );

      await conn.sobject("ContentDocumentLink").destroy(contentDocumentLinks);
      await conn.sobject("ContentVersion").destroy(contentDocumentIds);

      console.log(`Successfully deleted user data with ID: ${userId}`);
      return true; // Deletion was successful
    } else {
      console.error(`Failed to delete user data with ID: ${userId}`);
      return false; // Deletion failed
    }
  } catch (error) {
    console.error("Error deleting user data from Salesforce:", error);
    throw error;
  }
}

async function updateSoloParentData(userId, updatedData) {
  try {
    // Use the update method to update the record with the specified ID
    const updatedRecord = await conn
      .sobject("Solo_Parent_Application_Form__c")
      .update({ Id: userId, ...updatedData });

    // Check if the update was successful
    if (updatedRecord.success) {
      console.log(`Successfully updated user data with ID: ${userId}`);
      return true; // Update was successful
    } else {
      console.error(`Failed to update user data with ID: ${userId}`);
      return false; // Update failed
    }
  } catch (error) {
    console.error("Error updating user data in Salesforce:", error);
    throw error;
  }
}

async function userLogin(req, res) {
  const { username, password } = req.body;

  try {
    // Query Salesforce to find the user with the provided username
    const result = await conn.query(
      `SELECT OwnerId, Solo_Parent_Application__c, Solo_Parent_Application__r.Surname__c, Solo_Parent_Application__r.Given_Name__c,
      Solo_Parent_Application__r.Middle_Name__c FROM Account WHERE Name = '${username}' LIMIT 1`
    );

    if (result.totalSize === 1) {
      // User found, check the provided password
      const user = result.records[0];

      const trimmedEnteredPassword = password.trim();

      if (user.Password__c != trimmedEnteredPassword) {
        // Password is correct, return user information
        res.json({
          success: true,
          message: "Login successful",
          user: {
            userId: user.OwnerId,
            soloParentFormId: user.Solo_Parent_Application__c,
            name:
              user.Solo_Parent_Application__r.Surname__c +
              ", " +
              user.Solo_Parent_Application__r.Given_Name__c +
              " " +
              user.Solo_Parent_Application__r.Middle_Name__c,

            // password: Password__c,

            // Add more user details as needed
          },
        });
      } else {
        // Password is incorrect
        res.status(401).json({
          success: false,
          message: "Incorrect password.",
        });
        res.json(trimmedEnteredPassword);
      }
    } else {
      // User not found or invalid credentials
      res.status(401).json({ success: false, message: "Invalid credentials" });
    }
  } catch (error) {
    console.error("Error during login:", error);
    res.status(500).json({ success: false, message: "Internal server error" });
  }
}

async function fetchUserTickets(ticketNumber) {
  try {
    // Query for cases related to the user
    const cases = await conn.query(
      `SELECT CreatedDate, CaseNumber, Type, Status, Description, ContactEmail FROM Case WHERE CaseNumber = '${ticketNumber}'`
    );

    return cases.records;
  } catch (error) {
    console.error("Error fetching cases:", error);
    throw error;
  }
}

async function createUserTickets(req, res, next) {
  const { userId, type, description, clientName } = req.body;

  try {
    // Assuming you have a proper Salesforce connection (conn)
    const newCase = await conn.sobject("Case").create({
      AccountId: userId,
      Type: type,
      Origin: "Web",
      Description: description,
    });

    // You may want to associate the case with the clientName, assuming clientName is a field on the Case object
    await conn.sobject("Case").update({
      Id: newCase.Id,
      ClientName__c: clientName,
    });

    res.status(201).json({
      createdDate: newCase.CreatedDate,
      ticketId: newCase.CaseNumber,
      type: newCase.Type,
      status: newCase.Status,
      description: newCase.Description,
      contactEmail: newCase.ContactEmail,
    });
  } catch (error) {
    console.error("Error creating a new ticket:", error);
    res.status(500).json({ error: "Failed to create a new ticket", details: error.message });
    next(error);
  }
}

async function ticketNotif(res, req, next) {
  const { username, applicationNumber } = req.body;

  try {
    // Logic to create or update the custom object record in Salesforce
    // ...

    res
      .status(200)
      .json({ success: true, message: "Notification sent successfully" });
  } catch (error) {
    console.error("Error sending notification:", error);
    res
      .status(500)
      .json({ success: false, message: "Failed to send notification" });
    next(error);
  }
}
// Export the function
module.exports = {
  createSoloParentAccount,
  readSoloParentDataById,
  deleteSoloParentData,
  updateSoloParentData,
  readAllSoloParentData,
  userLogin,
  fetchUserTickets,
  createUserTickets,
  ticketNotif,
};

Additional Information

I’ve verified that the server is running on http://localhost:3001.
CORS headers on the server are configured to allow requests from my React app.

Error Details

Error submitting ticket: AxiosError {message: ‘Network Error’, name: ‘AxiosError’, code: ‘ERR_NETWORK’, config: {…}, request: XMLHttpRequest, …}

Question

  • Has anyone encountered a similar issue with Axios “Network Error” and resolved it successfully?
  • Are there specific configurations or settings I should check on the server or in my Axios request?
  • Any suggestions on how to troubleshoot and fix this issue?

I appreciate any help or insights you can provide!

Load More button

I have this code, for gallery cards. I used CSS, Bootstrap and little JS. I need to make load more button for tablet and mobile devices. I tried it but it only work when there are all cards. When I filter card, my load more button doesn’t work. I don’t have big knowledge in JavaScript, so that’s why I’m asking these question.

document
        .querySelector("#filter-coding")
        .addEventListener("change", filterCoding);
      document
        .querySelector("#filter-design")
        .addEventListener("change", filterDesign);
      document
        .querySelector("#filter-marketing")
        .addEventListener("change", filterMarketing);

      function filterCoding() {
        hideAllCards();

        if (document.querySelector("#filter-coding").checked) {
          var codingCards = document.querySelectorAll(".coding");
          codingCards.forEach((codingCard) => {
            codingCard.style.display = "inline-block";
          });

          document.querySelector("#filter-design").checked = false;
          document.querySelector("#filter-marketing").checked = false;
        } else {
          showAllCards();
        }
      }

      function filterDesign() {
        hideAllCards();

        if (document.querySelector("#filter-design").checked) {
          var designCards = document.querySelectorAll(".design");
          designCards.forEach((designCard) => {
            designCard.style.display = "inline-block";
          });

          document.querySelector("#filter-coding").checked = false;
          document.querySelector("#filter-marketing").checked = false;
        } else {
          showAllCards();
        }
      }

      function filterMarketing() {
        hideAllCards();

        if (document.querySelector("#filter-marketing").checked) {
          var marketingCards = document.querySelectorAll(".marketing");
          marketingCards.forEach((marketingCard) => {
            marketingCard.style.display = "inline-block";
          });

          document.querySelector("#filter-coding").checked = false;
          document.querySelector("#filter-design").checked = false;
        } else {
          showAllCards();
        }
      }

      function hideAllCards() {
        var allCards = document.querySelectorAll(".card-js");

        allCards.forEach((card) => {
          card.style.display = "none";
        });
      }

      function showAllCards() {
        var allCards = document.querySelectorAll(".card-js");

        allCards.forEach((card) => {
          card.style.display = "inline-block";
        });
      }
<!-- Filters -->
    <div class="filters d-flex align-items-stretch flex-column flex-lg-row">
      <input type="checkbox" id="filter-marketing" /><label
        class="filter-item bg-dark text-light p-4"
        for="filter-marketing"
      >
        <div class="row">
          <div class="col-10">
            <h3>Проекти на студенти по академијата за маркетинг</h3>
          </div>
          <div class="col-2 text-center align-self-center">
            <i class="fa-solid fa-circle-check text-dark"></i>
          </div>
        </div>
      </label>

      <input type="checkbox" id="filter-coding" /><label
        class="filter-item bg-dark text-light p-4"
        for="filter-coding"
      >
        <div class="row">
          <div class="col-10">
            <h3>Проекти на студенти по академијата за програмирање</h3>
          </div>
          <div class="col-2 text-center align-self-center">
            <i class="fa-solid fa-circle-check text-dark"></i>
          </div>
        </div>
      </label>

      <input type="checkbox" id="filter-design" /><label
        class="filter-item bg-dark text-light p-4"
        for="filter-design"
      >
        <div class="row">
          <div class="col-10">
            <h3>Проекти на студенти по академијата за дизајн</h3>
          </div>
          <div class="col-2 text-center align-self-center">
            <i class="fa-solid fa-circle-check text-dark"></i>
          </div>
        </div>
      </label>
    </div>
    
    
    <!-- Cards -->
    <h2 class="text-center text-dark py-5">Проекти</h2>
    <div class="card-container">
      <div class="gallery-cards d-flex flex-wrap">
        <!-- Card -->
        <div class="card-js flex-33 coding">
          <div class="flex-inner">
            <a href="#" class="m-right">
              <div class="card card-item">
                <img
                  src="./images/StockSnap_DOLNAISHLZ.jpg"
                  class="card-img-top"
                  alt="Image"
                />
                <div class="card-body">
                  <span class="py-1 px-3">Академија за Програмирање</span>
                  <h4 class="fw-bold mt-2">
                    Име на проектот стои овде во две линии
                  </h4>
                  <p>
                    Краток опис во кој студентите ќе можат да опишат за што се
                    работи во проектот.
                  </p>
                  <p class="date mt-3 mb-4 fw-bold">Април - Октомври 2019</p>
                  <a href="#" class="btn-style doznaj float-end px-5"
                    >Дознај повеќе</a
                  >
                </div>
              </div>
            </a>
          </div>
        </div>
        <!-- Card -->
        <div class="card-js flex-33 coding">
          <div class="flex-inner">
            <a href="#" class="m-right">
              <div class="card card-item">
                <img
                  src="./images/StockSnap_DOLNAISHLZ.jpg"
                  class="card-img-top"
                  alt="Image"
                />
                <div class="card-body">
                  <span class="py-1 px-3">Академија за Програмирање</span>
                  <h4 class="fw-bold mt-2">
                    Име на проектот стои овде во две линии
                  </h4>
                  <p>
                    Краток опис во кој студентите ќе можат да опишат за што се
                    работи во проектот.
                  </p>
                  <p class="date mt-3 mb-4 fw-bold">Април - Октомври 2019</p>
                  <a href="#" class="btn-style doznaj float-end px-5"
                    >Дознај повеќе</a
                  >
                </div>
              </div>
            </a>
          </div>
        </div>
        <!-- Card -->
        <div class="card-js flex-33 coding">
          <div class="flex-inner">
            <a href="#" class="m-right">
              <div class="card card-item">
                <img
                  src="./images/StockSnap_DOLNAISHLZ.jpg"
                  class="card-img-top"
                  alt="Image"
                />
                <div class="card-body">
                  <span class="py-1 px-3">Академија за Програмирање</span>
                  <h4 class="fw-bold mt-2">
                    Име на проектот стои овде во две линии
                  </h4>
                  <p>
                    Краток опис во кој студентите ќе можат да опишат за што се
                    работи во проектот.
                  </p>
                  <p class="date mt-3 mb-4 fw-bold">Април - Октомври 2019</p>
                  <a href="#" class="btn-style doznaj float-end px-5"
                    >Дознај повеќе</a
                  >
                </div>
              </div>
            </a>
          </div>
        </div>
        <!-- Card -->
        <div class="card-js flex-33 coding">
          <div class="flex-inner">
            <a href="#" class="m-right">
              <div class="card card-item">
                <img
                  src="./images/StockSnap_DOLNAISHLZ.jpg"
                  class="card-img-top"
                  alt="Image"
                />
                <div class="card-body">
                  <span class="py-1 px-3">Академија за Програмирање</span>
                  <h4 class="fw-bold mt-2">
                    Име на проектот стои овде во две линии
                  </h4>
                  <p>
                    Краток опис во кој студентите ќе можат да опишат за што се
                    работи во проектот.
                  </p>
                  <p class="date mt-3 mb-4 fw-bold">Април - Октомври 2019</p>
                  <a href="#" class="btn-style doznaj float-end px-5"
                    >Дознај повеќе</a
                  >
                </div>
              </div>
            </a>
          </div>
        </div>
        <!-- Card -->
        <div class="card-js flex-33 coding">
          <div class="flex-inner">
            <a href="#" class="m-right">
              <div class="card card-item">
                <img
                  src="./images/StockSnap_DOLNAISHLZ.jpg"
                  class="card-img-top"
                  alt="Image"
                />
                <div class="card-body">
                  <span class="py-1 px-3">Академија за Програмирање</span>
                  <h4 class="fw-bold mt-2">
                    Име на проектот стои овде во две линии
                  </h4>
                  <p>
                    Краток опис во кој студентите ќе можат да опишат за што се
                    работи во проектот.
                  </p>
                  <p class="date mt-3 mb-4 fw-bold">Април - Октомври 2019</p>
                  <a href="#" class="btn-style doznaj float-end px-5"
                    >Дознај повеќе</a
                  >
                </div>
              </div>
            </a>
          </div>
        </div>
        <!-- Card -->
        <div class="card-js flex-33 coding">
          <div class="flex-inner">
            <a href="#" class="m-right">
              <div class="card card-item">
                <img
                  src="./images/StockSnap_DOLNAISHLZ.jpg"
                  class="card-img-top"
                  alt="Image"
                />
                <div class="card-body">
                  <span class="py-1 px-3">Академија за Програмирање</span>
                  <h4 class="fw-bold mt-2">
                    Име на проектот стои овде во две линии
                  </h4>
                  <p>
                    Краток опис во кој студентите ќе можат да опишат за што се
                    работи во проектот.
                  </p>
                  <p class="date mt-3 mb-4 fw-bold">Април - Октомври 2019</p>
                  <a href="#" class="btn-style doznaj float-end px-5"
                    >Дознај повеќе</a
                  >
                </div>
              </div>
            </a>
          </div>
        </div>
        <!-- Card -->
        <div class="card-js flex-33 coding">
          <div class="flex-inner">
            <a href="#" class="m-right">
              <div class="card card-item">
                <img
                  src="./images/StockSnap_DOLNAISHLZ.jpg"
                  class="card-img-top"
                  alt="Image"
                />
                <div class="card-body">
                  <span class="py-1 px-3">Академија за Програмирање</span>
                  <h4 class="fw-bold mt-2">
                    Име на проектот стои овде во две линии
                  </h4>
                  <p>
                    Краток опис во кој студентите ќе можат да опишат за што се
                    работи во проектот.
                  </p>
                  <p class="date mt-3 mb-4 fw-bold">Април - Октомври 2019</p>
                  <a href="#" class="btn-style doznaj float-end px-5"
                    >Дознај повеќе</a
                  >
                </div>
              </div>
            </a>
          </div>
        </div>
        <!-- Card -->
        <div class="card-js flex-33 coding">
          <div class="flex-inner">
            <a href="#" class="m-right">
              <div class="card card-item">
                <img
                  src="./images/StockSnap_DOLNAISHLZ.jpg"
                  class="card-img-top"
                  alt="Image"
                />
                <div class="card-body">
                  <span class="py-1 px-3">Академија за Програмирање</span>
                  <h4 class="fw-bold mt-2">
                    Име на проектот стои овде во две линии
                  </h4>
                  <p>
                    Краток опис во кој студентите ќе можат да опишат за што се
                    работи во проектот.
                  </p>
                  <p class="date mt-3 mb-4 fw-bold">Април - Октомври 2019</p>
                  <a href="#" class="btn-style doznaj float-end px-5"
                    >Дознај повеќе</a
                  >
                </div>
              </div>
            </a>
          </div>
        </div>
        <!-- Card -->
        <div class="card-js flex-33 coding">
          <div class="flex-inner">
            <a href="#" class="m-right">
              <div class="card card-item">
                <img
                  src="./images/StockSnap_DOLNAISHLZ.jpg"
                  class="card-img-top"
                  alt="Image"
                />
                <div class="card-body">
                  <span class="py-1 px-3">Академија за Програмирање</span>
                  <h4 class="fw-bold mt-2">
                    Име на проектот стои овде во две линии
                  </h4>
                  <p>
                    Краток опис во кој студентите ќе можат да опишат за што се
                    работи во проектот.
                  </p>
                  <p class="date mt-3 mb-4 fw-bold">Април - Октомври 2019</p>
                  <a href="#" class="btn-style doznaj float-end px-5"
                    >Дознај повеќе</a
                  >
                </div>
              </div>
            </a>
          </div>
        </div>
        <!-- Card -->
        <div class="card-js flex-33 coding">
          <div class="flex-inner">
            <a href="#" class="m-right">
              <div class="card card-item">
                <img
                  src="./images/StockSnap_DOLNAISHLZ.jpg"
                  class="card-img-top"
                  alt="Image"
                />
                <div class="card-body">
                  <span class="py-1 px-3">Академија за Програмирање</span>
                  <h4 class="fw-bold mt-2">
                    Име на проектот стои овде во две линии
                  </h4>
                  <p>
                    Краток опис во кој студентите ќе можат да опишат за што се
                    работи во проектот.
                  </p>
                  <p class="date mt-3 mb-4 fw-bold">Април - Октомври 2019</p>
                  <a href="#" class="btn-style doznaj float-end px-5"
                    >Дознај повеќе</a
                  >
                </div>
              </div>
            </a>
          </div>
        </div>
        <!-- Card -->
        <div class="card-js flex-33 design">
          <div class="flex-inner">
            <a href="#" class="m-right">
              <div class="card card-item">
                <img
                  src="./images/StockSnap_DOLNAISHLZ.jpg"
                  class="card-img-top"
                  alt="Image"
                />
                <div class="card-body">
                  <span class="py-1 px-3">Академија за Дизајн</span>
                  <h4 class="fw-bold mt-2">
                    Име на проектот стои овде во две линии
                  </h4>
                  <p>
                    Краток опис во кој студентите ќе можат да опишат за што се
                    работи во проектот.
                  </p>
                  <p class="date mt-3 mb-4 fw-bold">Април - Октомври 2019</p>
                  <a href="#" class="btn-style doznaj float-end px-5"
                    >Дознај повеќе</a
                  >
                </div>
              </div>
            </a>
          </div>
        </div>
        <!-- Card -->
        <div class="card-js flex-33 design">
          <div class="flex-inner">
            <a href="#" class="m-right">
              <div class="card card-item">
                <img
                  src="./images/StockSnap_DOLNAISHLZ.jpg"
                  class="card-img-top"
                  alt="Image"
                />
                <div class="card-body">
                  <span class="py-1 px-3">Академија за Дизајн</span>
                  <h4 class="fw-bold mt-2">
                    Име на проектот стои овде во две линии
                  </h4>
                  <p>
                    Краток опис во кој студентите ќе можат да опишат за што се
                    работи во проектот.
                  </p>
                  <p class="date mt-3 mb-4 fw-bold">Април - Октомври 2019</p>
                  <a href="#" class="btn-style doznaj float-end px-5"
                    >Дознај повеќе</a
                  >
                </div>
              </div>
            </a>
          </div>
        </div>
        <!-- Card -->
        <div class="card-js flex-33 design">
          <div class="flex-inner">
            <a href="#" class="m-right">
              <div class="card card-item">
                <img
                  src="./images/StockSnap_DOLNAISHLZ.jpg"
                  class="card-img-top"
                  alt="Image"
                />
                <div class="card-body">
                  <span class="py-1 px-3">Академија за Дизајн</span>
                  <h4 class="fw-bold mt-2">
                    Име на проектот стои овде во две линии
                  </h4>
                  <p>
                    Краток опис во кој студентите ќе можат да опишат за што се
                    работи во проектот.
                  </p>
                  <p class="date mt-3 mb-4 fw-bold">Април - Октомври 2019</p>
                  <a href="#" class="btn-style doznaj float-end px-5"
                    >Дознај повеќе</a
                  >
                </div>
              </div>
            </a>
          </div>
        </div>
        <!-- Card -->
        <div class="card-js flex-33 design">
          <div class="flex-inner">
            <a href="#" class="m-right">
              <div class="card card-item">
                <img
                  src="./images/StockSnap_DOLNAISHLZ.jpg"
                  class="card-img-top"
                  alt="Image"
                />
                <div class="card-body">
                  <span class="py-1 px-3">Академија за Дизајн</span>
                  <h4 class="fw-bold mt-2">
                    Име на проектот стои овде во две линии
                  </h4>
                  <p>
                    Краток опис во кој студентите ќе можат да опишат за што се
                    работи во проектот.
                  </p>
                  <p class="date mt-3 mb-4 fw-bold">Април - Октомври 2019</p>
                  <a href="#" class="btn-style doznaj float-end px-5"
                    >Дознај повеќе</a
                  >
                </div>
              </div>
            </a>
          </div>
        </div>
        <!-- Card -->
        <div class="card-js flex-33 marketing">
          <div class="flex-inner">
            <a href="#" class="m-right">
              <div class="card card-item">
                <img
                  src="./images/StockSnap_DOLNAISHLZ.jpg"
                  class="card-img-top"
                  alt="Image"
                />
                <div class="card-body">
                  <span class="py-1 px-3">Академија за Маркетинг</span>
                  <h4 class="fw-bold mt-2">
                    Име на проектот стои овде во две линии
                  </h4>
                  <p>
                    Краток опис во кој студентите ќе можат да опишат за што се
                    работи во проектот.
                  </p>
                  <p class="date mt-3 mb-4 fw-bold">Април - Октомври 2019</p>
                  <a href="#" class="btn-style doznaj float-end px-5"
                    >Дознај повеќе</a
                  >
                </div>
              </div>
            </a>
          </div>
        </div>
        <!-- Card -->
        <div class="card-js flex-33 marketing">
          <div class="flex-inner">
            <a href="#" class="m-right">
              <div class="card card-item">
                <img
                  src="./images/StockSnap_DOLNAISHLZ.jpg"
                  class="card-img-top"
                  alt="Image"
                />
                <div class="card-body">
                  <span class="py-1 px-3">Академија за Маркетинг</span>
                  <h4 class="fw-bold mt-2">
                    Име на проектот стои овде во две линии
                  </h4>
                  <p>
                    Краток опис во кој студентите ќе можат да опишат за што се
                    работи во проектот.
                  </p>
                  <p class="date mt-3 mb-4 fw-bold">Април - Октомври 2019</p>
                  <a href="#" class="btn-style doznaj float-end px-5"
                    >Дознај повеќе</a
                  >
                </div>
              </div>
            </a>
          </div>
        </div>
        <!-- Card -->
        <div class="card-js flex-33 marketing">
          <div class="flex-inner">
            <a href="#" class="m-right">
              <div class="card card-item">
                <img
                  src="./images/StockSnap_DOLNAISHLZ.jpg"
                  class="card-img-top"
                  alt="Image"
                />
                <div class="card-body">
                  <span class="py-1 px-3">Академија за Маркетинг</span>
                  <h4 class="fw-bold mt-2">
                    Име на проектот стои овде во две линии
                  </h4>
                  <p>
                    Краток опис во кој студентите ќе можат да опишат за што се
                    работи во проектот.
                  </p>
                  <p class="date mt-3 mb-4 fw-bold">Април - Октомври 2019</p>
                  <a href="#" class="btn-style doznaj float-end px-5"
                    >Дознај повеќе</a
                  >
                </div>
              </div>
            </a>
          </div>
        </div>
        <!-- Card -->
        <div class="card-js flex-33 marketing">
          <div class="flex-inner">
            <a href="#" class="m-right">
              <div class="card card-item">
                <img
                  src="./images/StockSnap_DOLNAISHLZ.jpg"
                  class="card-img-top"
                  alt="Image"
                />
                <div class="card-body">
                  <span class="py-1 px-3">Академија за Маркетинг</span>
                  <h4 class="fw-bold mt-2">
                    Име на проектот стои овде во две линии
                  </h4>
                  <p>
                    Краток опис во кој студентите ќе можат да опишат за што се
                    работи во проектот.
                  </p>
                  <p class="date mt-3 mb-4 fw-bold">Април - Октомври 2019</p>
                  <a href="#" class="btn-style doznaj float-end px-5"
                    >Дознај повеќе</a
                  >
                </div>
              </div>
            </a>
          </div>
        </div>
        <!-- Card -->
        <div class="card-js flex-33 marketing">
          <div class="flex-inner">
            <a href="#" class="m-right">
              <div class="card card-item">
                <img
                  src="./images/StockSnap_DOLNAISHLZ.jpg"
                  class="card-img-top"
                  alt="Image"
                />
                <div class="card-body">
                  <span class="py-1 px-3">Академија за Маркетинг</span>
                  <h4 class="fw-bold mt-2">
                    Име на проектот стои овде во две линии
                  </h4>
                  <p>
                    Краток опис во кој студентите ќе можат да опишат за што се
                    работи во проектот.
                  </p>
                  <p class="date mt-3 mb-4 fw-bold">Април - Октомври 2019</p>
                  <a href="#" class="btn-style doznaj float-end px-5"
                    >Дознај повеќе</a
                  >
                </div>
              </div>
            </a>
          </div>
        </div>
        <!-- Card -->
        <div class="card-js flex-33 marketing">
          <div class="flex-inner">
            <a href="#" class="m-right">
              <div class="card card-item">
                <img
                  src="./images/StockSnap_DOLNAISHLZ.jpg"
                  class="card-img-top"
                  alt="Image"
                />
                <div class="card-body">
                  <span class="py-1 px-3">Академија за Маркетинг</span>
                  <h4 class="fw-bold mt-2">
                    Име на проектот стои овде во две линии
                  </h4>
                  <p>
                    Краток опис во кој студентите ќе можат да опишат за што се
                    работи во проектот.
                  </p>
                  <p class="date mt-3 mb-4 fw-bold">Април - Октомври 2019</p>
                  <a href="#" class="btn-style doznaj float-end px-5"
                    >Дознај повеќе</a
                  >
                </div>
              </div>
            </a>
          </div>
        </div>
      </div>
      <div id="load-more" class="text-center btn-style">load-more</div>
    </div>

How to make smooth easing for complex path in Anime.js?

I use Anime.js v 3.2.2.

An object should move by a complex path – an array of {x, y} coordinates.

The problem: The “easing” is not applied to the whole animation. Instead easing applies for each “step” from point to point.

Question: How to apply easing for whole animation with curved path (more that 2 {x,y} coordinates)?

   // This works well
    anime({
      targets: simpleStateProxy,
      x: 250,
      duration: 1000,
      round: 1,
      easing: 'easeInCubic'
    });
//This doesn't work as expected (animation is not smooth, easing is not applied for whole animation
anime({
      targets: complexStateProxy,
      x: [
        { value: 50 },
        { value: 100 },
        { value: 150 },
        { value: 200 },
        { value: 250 },
      ],
      y: [
        { value: 20 },
        { value: 30 },
        { value: 30 },
        { value: 20 },
        { value: 0 },
      ],
      duration: 1000,
      round: 1,
      easing: 'easeInCubic', //
      complete: () => console.log('complex done')
    });

Please check code snippet or jsfiddle.

Thanks.

P.S. If that’s not possible in AnimeJS, maybe you could propose any other library which can do that? Preferably with an open license.

const simple = document.getElementById('simple');
const complex = document.getElementById('complex');

const simpleState = { x: 0, y: 0 }  //x - left, y - top
const complexState = { x: 0, y: 0 }  //x - left, y - top

// do not pay attention to this
const simpleStateProxy = new Proxy(simpleState, {
  set: (target, key, value) => {
    target[key] = value;
    simple.style.left = `${value}px`;
    return true;
  },
});

// do not pay attention to this
const complexStateProxy = new Proxy(complexState, {
  set: (target, key, value) => {
    target[key] = value;
    if (key === 'x') complex.style.left = `${value}px`;
    if (key === 'y') complex.style.top = `${value}px`;
    return true;
  },
});


// Animation of a "simple" box
anime({
  targets: simpleStateProxy,
  x: 250,
  duration: 1000,
  round: 1,
  easing: 'easeInCubic',
  complete: () => console.log('simple done')
});

// Animation of a "complex" box
anime({
  targets: complexStateProxy,
  x: [
    { value: 50 },
    { value: 100 },
    { value: 150 },
    { value: 200 },
    { value: 250 },
  ],
  y: [
    { value: 20 },
    { value: 30 },
    { value: 30 },
    { value: 20 },
    { value: 0 },
  ],
  duration: 1000,
  round: 1,
  easing: 'easeInCubic',
});
.container {
  position: relative;
}

.container:last-of-type {
  top: 60px;
}


.box {
  display: flex;
  position: relative;
  left: 0px;
  width: 50px;
  height: 50px;
  background-color: red;
  font-size: 14px;
  font-weight: 500;
  align-items: center;
  flex-direction: column;
  justify-content: center;
  color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.2/anime.min.js"></script>
<div class="container">
  <div id="simple" class="box">simple</div>
</div>

<div class="container">
  <div id="complex" class="box">complex</div>
</div>