Apart Area Chart not showing Data if type Datetime is selected

I am tryng to display data using Apex Chart, the chart is working fine dynamically if its only DATE type. When I use date range search (switching to DATETIME dynamically) to query database the AREA chart does not show chart but only shows figures when you hover on the chart, on the other hand if i change type to BAR it works fine.

What could be wrong? What am I missing?
Please see the image here attached
enter image description here
here is the PHP code

 $months = array();
    $value1 = array();
     // $value2 = array(); ...etc
    for( $m = 1; $m <= 12; $m++ ) {
      try{
            // Check if TO DATE AND FROM DATE fields are not empty
        if(!empty($from_date) || !empty($to_date)) { 
          $selectdate1 = strtotime($from_date); 
          $selectdate2 = strtotime($to_date); 
    
          for ($nowDate = $selectdate1; $nowDate <= $selectdate2;  
            $nowDate += (86400)) { 
    
            $actArrayDate = date('Y-m-d', $nowDate); 
    
            $stmt = $conn->prepare("SELECT SUM(value) as value1 etc FROM  table  WHERE (date(month) IN (:timdate)) AND country LIKE :country AND status = :status");
            $stmt->execute(['timdate'=>$actArrayDate, 'country'=>$country, 'country'=>'%'.$country.'%', 'status'=>1]);
    
          } 
    
    
        } //end check dates
        else{
          // Check if both country and continent fields are not empty
    
          $stmt = $conn->prepare("SELECT SUM(value) as value1 etc FROM  table  WHERE MONTH(month)=:month AND YEAR(month)=:year AND country LIKE :country AND status = :status");
          $stmt->execute(['month'=>$m, 'year'=>$year, 'country'=>'%'.$country.'%', 'status'=>1]);
        }
    
        $valueRow = $stmt->fetch(PDO::FETCH_ASSOC);
        $value1 = $valueRow['value1'];
           // .....value2 etc....
        array_push($value1, number_format( sprintf( '%.2f', $value1), 2, '.', '' ));   
    // ..........valu2 .....etc
      } // end try
    
        catch(PDOException $e){
          $_SESSION['error'] ='Something went wrong with the data'.$e->getMessage();
        }
    
        $num = str_pad( $m, 2, 0, STR_PAD_LEFT );
        $month =  date('M', mktime(0, 0, 0, $m, 1));
        array_push($months, $month);
      }
    $value1 = json_encode($value1);
// $value2 = json_encode($value2);...etc
      // if (isset($_GET['from_date']) || isset($_GET['to_date'])) {
       if(!empty($from_date) || !empty($to_date)) { //Check if dates are not empty
        $selectedFromDate = $_GET['from_date'];
        $selectedToDate = $_GET['to_date'];
        $dateArray = array(); 
        $fromDate1 = strtotime($selectedFromDate); 
        $toDate2 = strtotime($selectedToDate); 
        for ($currentDate = $fromDate1; $currentDate <= $toDate2;  
          $currentDate += (86400)) { 
    
          $dateDetails = date('Y-m-d', $currentDate); 
          $dateArray[] = $dateDetails; 
        } 
    // Display the dates in array format 
        $months = json_encode($dateArray);
        $apexType = "datetime";
        $columWidth ='columnWidth: 300';
      }
    // }
      else{
        $months = json_encode($months);
        $apexType = "date";
        $columWidth ='';
      }

And here is the apex js code

 var options = {
  series: [  { name: "Value1 Label", data: <?php echo $value1; ?> }
    // { name: "Value2 Label", data: <?php echo $value2; ?>......etc },
    ],
  chart: {
    height: 350,
    stacked: true,
    type: 'area'
  },
  dataLabels: {
    enabled: false
  },
  colors: ['#color1', //color2...etc
    ],
  stroke: { curve: "smooth", lineCap: "round", width: 0 },
  fill: { type: "solid" },
  xaxis: {
   type: "<?php echo $apexType ?>",
   categories: <?php echo $months; ?>,
   labels: { style: { colors: colors.mutedColor, cssClass: "text-muted", fontFamily: base.defaultFontFamily } },
 },
 yaxis: {
  labels: { style: { colors: colors.mutedColor, cssClass: "text-muted", fontFamily: base.defaultFontFamily } },
},
legend: { position: "bottom", horizontalAlign: 'center', fontFamily: base.defaultFontFamily, fontWeight: 400,
labels: { colors: colors.mutedColor },
},
tooltip: {
  x: {
    format: 'dd/MM/yy HH:mm'
  },
},
};

var chart = new ApexCharts(document.querySelector("#areaChart"), options);
chart.render();

node js telegraf reply isn’t working inside a function

i tried to make a scraping telegram bot using node and telegraf
i did try replying message with the function but it replied the [promise object ] even though I used return in the function i tried replying inside if function and the bot didn’t replied at all
all the things i have tried are temporarily removed with comments so you can see them

here is the code :

import puppeteer from "puppeteer";
import { Telegraf } from "telegraf";

let input = "zesht"
// let textReply = "martike"
const bot = new Telegraf("bot token here")

const getData = async function() {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto(`https://fa.wikipedia.org/w/index.php?search=${input}&title=%D9%88%DB%8C%DA%98%D9%87%3A%D8%AC%D8%B3%D8%AA%D8%AC%D9%88&ns0=1` , { timeout : 0});

    
    const searchResult = await page.$(".mw-search-result-heading > a[data-serp-pos='0']" , {timeout : 0})
    // const maghaleLink = await searchResult.evaluate(el => el.href)
    
    if(searchResult == null){
       const maghale = await page.$('p');
       const textReply = await maghale.evaluate( el => el.textContent);
        // console.log(matn)
        // return matn
        // return await maghale.evaluate(el => el.textContent)
        bot.on("message" , async ctx=> { input = ctx.message.text , await ctx.reply(textReply)});
    }
    else{
        const maghaleLink = await searchResult.evaluate(el => el.href);
        await page.goto(maghaleLink);
        const maghale1 = await page.$('p');
        const textReply = await maghale1.evaluate( el => el.textContent);
        //  await maghale1.evaluate(el => el.textContent)
        // console.log(matn1)
        bot.on("message" , async ctx => { input = ctx.message.text ,await ctx.reply(textReply) }) ;
    }


    browser.close()
}

// const bot = new Telegraf("bot token here")

bot.start(ctx => ctx.reply("salam mashti"))
// bot.on("message" , async ctx => { await getData()} )
bot.on("message" , getData())
// bot.on("message" , async ctx=> { input = ctx.message.text; getData() ; await ctx.reply(textReply) })

bot.launch()

expected

replying with a text scraped from wikipedia

what happened

bot replies nothing or replies a text that is [promise object] or gives an error saying : unhandled error while processing message

How to Override Inherited :focus-visible Styles in a Chatbot Component?

I am integrating a chatbot into a parent website over which I have no CSS control. The parent site has CSS rules that apply box-shadow to elements when they are focused (using :focus-visible). These styles are affecting the input elements of my chatbot, particularly adding unwanted box-shadow.
enter image description here

I attempted to override these styles using the following CSS, but it has not been successful:

.message-input:focus {
  outline-color: red !important;
  box-shadow: none !important;
}

.message-input:focus:not(:focus-visible) {
  outline: 0 !important;
  box-shadow: none !important;
}

.v-text-field {
  outline: 0 !important;
  box-shadow: none !important;
}

Here’s the relevant part of my Vuetify 3 template code for the input element:

<div class="message-input-container">
  <v-text-field v-model="newMessage" label="Type a message..." class="message-input" @keydown.enter="sendMessage" ref="messageInput"></v-text-field>
  <v-btn icon class="send-button" @click="sendMessage">
    <v-icon>mdi-send</v-icon>
  </v-btn>
</div>

Could anyone suggest how I might successfully remove or override these inherited box-shadow styles from the parent website’s CSS? I’m particularly looking for a solution that works well with Vuetify 3 components.

Form Submit Event gets triggered when switching to edit mode

I have a React Component that displays user data and provides an option to edit the data in place.

When I click on the edit button, the form submit action is triggered.
I have marked the Edit button as type: button but this still keeps happening.

Component JSX

<form
  onSubmit={(event) => {
    event.preventDefault();
    console.log("Submit action triggered.");
  }}
>
  {isEdit ? (
    <div>
      <input type="text" defaultValue={obj.name} />
      <input type="text" defaultValue={obj.email} />
      <select defaultValue={obj.type}>
        <option value="user">User</option>
        <option value="admin">Admin</option>
      </select>
      <button type="submit">Save</button>
      <button type="reset" onClick={() => setIsEdit(false)}>
        Cancel
      </button>
    </div>
  ) : (
  <div>
    <span>{obj.name},</span>
    <span>{obj.email},</span>
    <span>{obj.type},</span>

    <button type="button" onClick={() => setIsEdit(true)}>
      Edit
    </button>
    <button type="button">Delete</button>
  </div>
  )}
</form>

Here is the link to a codesandbox example,

https://codesandbox.io/s/form-click-jz9lfd

One way I found to fix it is to put event.preventDefault() in the Edit Event handler.

My question is why is the form submit event being triggered on the edit button?

kurento group call node question and suggestions

Good Evening.

I have this code kurento-group-call-node and managed to convert it to version 7 of Kurento for audio only.
I would like to make some changes but my knowledge is not enough with pipelines and endpoints.
I want whoever joins the room not to connect directly to the microphone but when he wants to open/close the microphone and speak with a button.
Considering that if someone is already in the room and they are talking, he can still hear them even if he doesn’t have an open microphone.
If he wants to open a microphone, those who already have an open microphone can hear him.
If there is any other code that can do this I would really like to get it.

Thanks in advance!

I changed it as much as I could and with a button everyone opens their microphone but the others don’t hear him, they only hear him if they also open their microphone, while I would like anyone entering the room to be able to listen directly to those who have a microphone and if they want to join the conversation.

Avoid flickering while loading the page (due to CSS being loaded after the HTML text, I guess)

I already searched here in SO for a while, for sure already exists something, but probably I’m missing the correct terms to search.

I started recently to bundle all my front-end assets in a single bundle with webpack, but now when the page loads, the page flickers due to the fact (I guess), that CSS is loaded only after the HTML text.

How can I avoid this?

enter image description here

As mentioned, I’m using webpack to bundle all JS and CSS files. My webpack bundling script:

const path = require('path')
const colors = require('colors/safe')
const appRoot = require('app-root-path')
const webpack = require('webpack')
const CopyPlugin = require('copy-webpack-plugin')

const commonsDir = path.join(appRoot.path, '..', 'resources', 'routines', 'commons')
const { getFiles } = require(path.join(commonsDir, 'file.js'))

const srcDir = path.resolve(appRoot.path, 'src', 'public', 'src').replace(/\/g, '/')
const docsDir = path.resolve(appRoot.path, 'docs', 'dist').replace(/\/g, '/')
const destDir = path.resolve(appRoot.path, 'src', 'public', 'dist')

const mode = process.env.NODE_ENV === 'production' ? 'production' : 'development'
console.log('mode:', mode)

module.exports = async () => {
  // assemble JS files as entry points
  const jsFiles = [
    path.join(srcDir, 'js', 'index.js'),
    path.join(srcDir, 'js', 'import-bootstrap.js')
  ]
  const files = await getFiles(path.join(srcDir, 'js', 'routes'))
  jsFiles.push(...files.filter(f => path.extname(f) === '.js'))

  const JSentryPointsObj = {}
  jsFiles.forEach(file => {
    JSentryPointsObj[path.basename(file)] = file
  })

  webpack({
    entry: JSentryPointsObj,
    output: {
      filename: path.join('js', '[name]'),
      path: destDir,
      clean: true
    },
    module: {
      rules: [
        {
          test: /.png/,
          type: 'asset/resource'
        },
        {
          test: /.css$/i,
          use: ['style-loader', 'css-loader']
        },
        {
          test: /.(woff|woff2|eot|ttf|otf)$/i,
          type: 'asset/resource'
        }
      ]
    },
    plugins: [
      new CopyPlugin({
        patterns: [
          {
            from: path.posix.join('*'),
            context: srcDir
          },
          {
            from: path.posix.join('img', '**/*'),
            context: srcDir
          },
          {
            from: path.posix.join('icons', '**/*'),
            context: srcDir
          },
          {
            from: path.posix.join('*'),
            to: 'docs',
            context: docsDir
          }
        ]
      })
    ],
    mode: mode
  }, (err, stats) => {
    if (err || stats.hasErrors()) {
      if (err) {
        console.error(err)
        throw new Error(err)
      } else {
        console.log(
          stats.toString({
            chunks: false, // Makes the build much quieter
            colors: true // Shows colors in the console
          })
        )
        throw new Error(stats.toString())
      }
    } else {
      console.log(colors.green('nFront-end assets built into ' + path.relative(appRoot.path, destDir)))
    }
  })
}

Cannot use external function inside page.evaluate(), even after specifying page.addScriptTag(…) & page.exposeFunction(…)

I am scraping dynamic website with puppeteer. My goal is to be able to create as much generic scraping logic as possible, which will also remove a lot of boilerplate code. So for that reason, I created external function that scrapes the data, given certain parameters. The problem was that when I tried to use that function inside page.evaluate() puppeteer method, I ran into a ReferenceError that this function was not defined.

Did some research and the page.exposeFunction() & page.addScriptTag() came out as a possible solutions. However when I tried to use them inside my scraper, addScriptTag() wasn’t working and exposeFunction() didn’t give me the ability to access DOM elements inside the exposed function. I understood that exposeFunction() is being executed inside Node.js, while addScriptTag() – in the browser, but I don’t know how to proceed further with that information and if it is even valuable for my case.

Here is my scraper:

import { Browser } from "puppeteer";

import { dataMapper } from "../../utils/api/functions/data-mapper.js";

export const mainCategoryScraper = async (browser: Browser) => {
  const [page] = await browser.pages();

  await page.setUserAgent(
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"
  );

  await page.setRequestInterception(true);

  page.on("request", (req) => {
    if (
      req.resourceType() === "stylesheet" ||
      req.resourceType() === "font" ||
      req.resourceType() === "image"
    ) {
      req.abort();
    } else {
      req.continue();
    }
  });

  await page.goto("https://www.ozone.bg/pazeli-2d-3d/nastolni-igri", {
    waitUntil: "domcontentloaded",
  });

  /**
   * Function will execute in Node.js
   */
  // await page.exposeFunction('dataMapper', dataMapper);

  /**
   * The way of passing DOM elements to the function, because like that the function executes in the browser
   */
  // await page.addScriptTag({ content: `${dataMapper}` });

  const data = await page.evaluate(async () => {
    const contentContainer = document.querySelector(".col-main") as HTMLDivElement;

    const carousels = Array.from(
      contentContainer.querySelectorAll(".owl-item") as NodeListOf<HTMLDivElement>
    );

    const carouselsData = await dataMapper<HTMLDivElement>(carousels, ".title", "img", "a");

    return {
      carouselsData,
    };
  });
  await browser.close();

  return data;
};

And here is the dataMapper function:

import { PossibleTags } from "../typescript/types.js";

export const dataMapper = function <T extends HTMLDivElement>(items: Array<T>, ...selectors: string[]) {
  let hasTitle = false;

  for (const selector of selectors) {
    if (selector === ".title" || selector === "h3") {
      hasTitle = true;
      break;
    }
  }
  
  return items.map((item) => {
    const data: PossibleTags = {};

    return selectors.map((selector) => {
        
      const dataProp = item.querySelector(selector);

      switch (selector) {
        case ".title": {
          data["title"] = (dataProp as HTMLSpanElement)?.innerText;
          break;
        }
        case "h3": {
          data["title"] = (dataProp as HTMLHeadingElement)?.innerText;
          break;
        }
        case "h6": {
          data["subTitle"] = (dataProp as HTMLHeadingElement)?.innerText;
          break;
        }
        case "img": {
          if (!hasTitle) {
            data["img"] = (dataProp as HTMLImageElement)?.getAttribute("src") ?? undefined;
            break;
          }

          data["title"] = (dataProp as HTMLImageElement)?.getAttribute("alt") ?? undefined;
          break;
        }
        case "a": {
          data["url"] = (dataProp as HTMLAnchorElement)?.getAttribute("href") ?? undefined;
        }
        default: {
          throw new Error("Such selector is not yet added to the possible selectors");
        }
      }
    });
  });
};

When I use the page.exposeFunction('dataMapper', dataMapper);, it tells me that item.querySelector is not a function (inside dataMapper). And with await page.addScriptTag({ content: `${dataMapper}` });, it just throws error later on inside the page.evaluate, that dataMapper is not a function.

Update: when specifying path inside the addScriptTag, it still gives me: Error [ReferenceError]: dataMapper is not defined
*
Just to mention that the mainCategoryScraper * is later on used in scrapersHandler function, which decides what scraper to be executed, based on URL endpoint.

logic to compare two array of objects and need to add a matched field value [closed]

we need to check the masterId at each level in both the object
if its equal at each level than we need to check for ref,
if ref is equal than add the quantity of both unique ref.

let obj1 = {
  "obj": [
    {
      "name": "abc",
      "obj": [
        {
          "name": "def",
          "obj": [
            {
              "name": "ghi",
              "data": [
                {
                  "quantity": 1,
                  "ref": "ABCEFG"
                },
                {
                  "quantity": 1,
                  "ref": "HIJKLM"
                  },
                {
                  "quantity": 1,
                  "ref": "ABCDEF"
                }
              ],
              "masterId": "07a5b470"
            }
          ],
          "masterId": "07a5b470"
        }
      ],
      "masterId": "07a5b470"
    }
  ]
}

let obj2 = {
  "obj": [
    {
      "name": "abc",
      "obj": [
        {
          "name": "def",
          "obj": [
            {
              "name": "ghi",
              "data": [
                {
                  "quantity": 1,
                  "ref": "ABCEFG"
                },
                {
                  "quantity": 1,
                  "ref": "HIJKLM"
                },
                {
                  "quantity": 1,
                  "ref": "XYZ123"
                }
              ],
              "masterId": "07a5b470"
            }
          ],
          "masterId": "07a5b470"
        }
      ],
      "masterId": "07a5b470"
    }
  ]
}

Expected Output:

{
  "obj": [
    {
      "name": "abc",
      "obj": [
        {
          "name": "def",
          "obj": [
            {
              "name": "ghi",
              "data": [
                {
                  "quantity": 2,
                  "ref": "ABCEFG"
                },
                {
                  "quantity": 2,
                  "ref": "HIJKLM"
                },
                {
                  "quantity": 1,
                  "ref": "ABCDEF"
                },
                 {
                  "quantity": 1,
                  "ref": "XYZ123"
                }
              ],
              "masterId": "07a5b470"
            }
          ],
          "masterId": "07a5b470"
        }
      ],
      "masterId": "07a5b470"
    }
  ]
}

Heroku router error ActionController::RoutingError (No route matches [GET] “/assets/modules/seat_builder.js”)

The error that I am getting, in the Heroku server logs is this:

ActionController::RoutingError (No route matches [GET] "/assets/modules/seat_builder.js")

This error is popping up for every single module that I am importing into my seating_controller.js.

Module names

  • seat_builder.js
  • seat_editor.js
  • reservation.js
  • contingent.js
  • discount_input_builder.js

I am using Rails 7 with StimulusJS. I have a seating_controller.js that is importing modules from the modules directory in the app/javascript/modules dir (that dir was created by me). Below you can find the code snippets related to my issue:

I believe that here lies my issue this is how my manifest.js file looks now but I tried importing the modules here as well, which did not help anything…

// app/assets/config/manifest.js

//= link_tree ../images
//= link_tree ../../javascript .js
//= link_directory ../stylesheets .css
//= link_tree ../../../vendor/javascript .js

This is how my application.js file looks like:

// app/javascript/application.js

// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "@hotwired/turbo-rails"
import "controllers"
import "@rails/actioncable"

This is how my importmap.rb file looks like. I am importing the modules from the modules dir. Double checked the paths they should be correct…

# config/importmap.rb


# frozen_string_literal: true

# Pin npm packages by running ./bin/importmap

pin 'application'
pin '@hotwired/turbo-rails', to: 'turbo.min.js', preload: true
pin '@hotwired/stimulus', to: 'stimulus.min.js'
pin '@hotwired/stimulus-loading', to: 'stimulus-loading.js'
pin_all_from 'app/javascript/controllers', under: 'controllers'
pin_all_from 'app/javascript/modules', under: 'modules'
pin_all_from 'app/javascript/modules/theaters', under: 'modules/theaters'
pin '@rails/actioncable', to: '@rails--actioncable.js' # @7.1.3
pin '@rails/actioncable', to: 'actioncable.esm.js'
pin_all_from 'app/javascript/channels', under: 'channels'

Finally here is my seating_controller.js. For simplicity I am showing only the import paths as the actual code doesn’t seem to have any issues…

// app/javascript/controllers/seating_controller.js

import { Controller } from "@hotwired/stimulus";
import SeatBuilder from "../modules/seat_builder.js";
import SeatEditor from "../modules/seat_editor.js";
import SeatReservation from "../modules/reservation.js";
import Contingent from "../modules/contingent.js";
import DiscountInputBuilder from "../modules/discount_input_builder.js";

when they pick the vendor of prague ticket portal
// Connects to data-controller="seating"
export default class extends Controller {

  // Rest of the code here

}

Also I am importing other theater modules into the seat_builder.js module:

// app/javascript/modules/seat_builder.js


import DivadloBroadway from "./theaters/divadlo_broadway.js";
import ObecniDum from "./theaters/obecni_dum.js";
import KostelSvatehoMartinaVeZdi from "./theaters/kostel_svateho_martina_ve_zdi.js";

export default class SeatBuilder {

  // Rest of the code here

}

The idea is to keep the concerns separate by having one controller for everything seating related but adding mixins in form of modules. That seems to prove itself useful in development, but production is not happy… I have been banging my head against the wall with this error for ever. To me it seems that path to the assets is always relative to the manifest.js file. Because the ../modules/file_name.js path that I am using in the controller, if used in the manifest file would result in assets/modules/file_name.js but I am not sure where to go from here…

I hope this made sense, thank you in advance for your time and patience!

Experiencing FOUC with Basic Example of Material Web Components

I’m currently implementing a super basic example using Material Web Components as described in their official documentation on GitHub, but I’m encountering an issue with a Flash of Unstyled Content (FOUC) when the page loads. The components appear unstyled briefly before the correct styles are applied. I’m looking for insights into why this is happening and how to resolve it.
The issue occures only one the first load (I guess it should be cache work) so in order to observe it again a clean refresh is needed

ScrollIntoView does not take into account a right panel width

I have this TS code:

 public openPanel(widget: Widget): void {
    const doesWidgetHaveFields = this.widgetFormService.doesWidgetHaveFields(widget.widgetType);

    this.store.dispatch([
      doesWidgetHaveFields
        ? new SetRightPanelState(RightPanelState.Edit)
        : new SetRightPanelState(RightPanelState.Hidden)
   ]);

      const selectedWidget = this.options?.api?.getItemComponent?.(widget);

      setTimeout(() => {
        selectedWidget?.el.scrollIntoView({ behavior: 'smooth', block: 'end' });
      
      }, 2500);
    
  }

In the dispatch i set the right panel to be visible.

The right panel width is 500px

On the setTimeout the scrollIntoView doesn’t take in to a account the right panel width.

how can i fix this?

Uncaught (in promise) Error Showing while sending data response in node js and map function showing error in react

Here is the node js
getting error in promise

import express from "express";

const app = express();

const port = process.env.PORT || 3000;

app.get('/jokes', (req ,res) => {
  const jokes = [
    {
      id: 1,
      title: 'Why don't scientists trust atoms?',
      content: 'Because they make up everything!'
    },
    {
      id: 2,
      title: 'Did you hear about the mathematician who's afraid of negative numbers?',
      content: 'He'll stop at nothing to avoid them!'
    },
    {
      id: 3,
      title: 'Why did the scarecrow win an award?',
      content: 'Because he was outstanding in his field!'
    },
    {
      id: 4,
      title: 'Why don't skeletons fight each other?',
      content: 'They don't have the guts!'
    },
    {
      id: 5,
      title: 'What do you call fake spaghetti?',
      content: 'An impasta!'
    }
  ];

      res.send(jokes);        
    }); 


app.listen(port, () => {
  console.log(`Server at http://localhost:${port}`);
});

Error that i am getting

here is react code
Tried using map function in react file and i am getting uncaught TypeError: jokes.map is not a function

import  { useEffect, useState } from "react"
import React from "react"
import axios from 'axios'
import './App.css'
function App() {
  const [jokes, setJokes] = useState([])

  useEffect(() => {
   axios.get('http://localhost:3000/jokes')
   .then((response) =>{
    setJokes(response.data)
   })
   .catch((error) =>{
    setJokes(error)
   })
  }, [])
  

  return (
    <>
     <h1>Fullstack</h1>
      <p>JOKES : {jokes.length}</p>
      
      {
        jokes.map((joke,index) =>{
            <div key={joke.id} >
              <h3>{joke.title}</h3>
              <h3>{joke.title}</h3>
            </div>
        })
      }
    </>
  )
}
export default App

error in frontend

tried sending data using send and json both

wont able to map it in react error says jokes.map is not a function

Add val.hierarchy in array of objects

Here’s an array

const arr = [
  {name: "Earth", id: 1, parent_id: -1},
  {name: "Europe", id: 2, parent_id: 1},
  {name: America": id: 3, parent_id: 1},
  {name: "Asia", id: 4, parent_id: 1}
];

I need to add a hierarchy key to each element of the array, which will contain the array

const arr = [
  {name: "Earth", id: 1, parent_id: -1, hierarchy: ["Earth"]},
  {name: "Europe", id: 2, parent_id: 1, hierarchy: ["Earth", "Europe"]},
  {name: America": id: 3, parent_id: 1, hierarchy: ["Earth", "America"]},
  {name: "Asia", id: 4, parent_id: 1, hierarchy: ["Earth", "Asia"]}
];

I’m trying to do this using lodash find

const parent = _.find(arr, { id: val.parent_id });

    if (parent === undefined) {
      val.hierarchy = [val.id];
    } else {
      val.hierarchy = [...parent.hierarchy, val.id];
    }

But I always get parent === undefined

What would be a viable and more flexible alternative to using snapshot in Angular 16?

I have been working on an SPA with Angular 16, TypeScript and The Movie Database (TMDB).

I run into a strange issue while working on a list movies by genre feature.

In `appservicesmovie-service.service.ts` I have:

import { environment } from '../../environments/environment';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { GenreResponse } from '../models/Genre';

@Injectable({
  providedIn: 'root'
})

export class MovieService {
  constructor(private http: HttpClient) { }

  public getAllMovieGenres(): Observable<GenreResponse> {
    return this.http.get<GenreResponse>(`${environment.apiUrl}/genre/movie/list?api_key=${environment.apiKey}`);
  }

  public getMoviesByGenre(id: Number): Observable<MovieResponse> {
    return this.http.get<MovieResponse>(`${environment.apiUrl}/discover/movie?api_key=${environment.apiKey}&with_genres=${id}`);
  }
}

I use the above methods in the MoviesByGenre component:

import { Component } from '@angular/core';
import { GenreResponse, Genre } from '../../models/Genre';
import { MovieResponse, Movie } from '../../models/Movie';
import { MovieService } from '../../services/movie-service.service';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-movies-by-genre',
  templateUrl: './movies-by-genre.component.html',
  styleUrls: ['./movies-by-genre.component.scss']
})

export class MoviesByGenre {

  constructor(
    private activatedRoute: ActivatedRoute,
    private movieService: MovieService
  ) { }

  public genreName: string | undefined = '';

  public movieResponse!: MovieResponse;
  public movies: Movie[] | undefined = [];

  public genreResponse!: GenreResponse;
  public genres: Genre[] | undefined = [];

  public getMoviesByGenre(): void {

    // Get genre id (from URL parameter)
    const genre_id = Number(this.activatedRoute.snapshot.paramMap.get('id'));

    // Get genre name from genres array
    this.movieService.getAllMovieGenres().subscribe((response) => {
      this.genreResponse = response;
      this.genres = this.genreResponse.genres;

      if (this.genres && this.genres.length) {
        let currentGenre = this.genres.find(genre => genre.id === genre_id);
        if (currentGenre) {
          this.genreName = currentGenre.name || '';
          this.movieService.defaultTitle = this.genreName;
        }
      }
    });

    // Get movies by genre id
    this.movieService.getMoviesByGenre(genre_id).subscribe((response) => {
      this.movieResponse = response;
      this.movies = this.movieResponse.results;
    })
  }

  ngOnInit() {
    this.getMoviesByGenre();
  }
}

The problem

Whenever I display movies of a certain genre and try to navigate to another genre, for instance, from localhost:4200/by-genre/12 to localhost:4200/by-genre/18, the nre data is not loaded (even though the URL does change).

enter image description here

In other words using this to get and use the genre_id fails:

const genre_id = Number(this.activatedRoute.snapshot.paramMap.get('id'));

Questions

  1. What am I doing wrong?
  2. What is the easiest and most reliable way to fix this issue?