Remix No route matches URL

I have brand new Remix SPA project with simple nested route

  1. Home
  2. Protocol
  3. Protocol/[protocolId]

And I setup the project as shown in the repo https://stackblitz.com/~/github.com/pavankjadda/remix-vite-spa

All routes work except nested route protocol/[protocolId]. I did follow instructions from official docs: https://remix.run/docs/en/main/file-conventions/routes#folders-for-organization. You can see same Stackblitz preview.

Why is this Scraping Function returning an empty array?

const unirest = require("unirest");
const cheerio = require("cheerio");

const getOrganicData = () => {
  return unirest
    .get("https://www.google.com/search?q=apple+linkedin&gl=us&hl=en")
    .headers({
      "User-Agent":
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36",
    })
    .then((response) => {
      let $ = cheerio.load(response.body);

      let titles = [];
      let links = [];
      let snippets = [];
      let displayedLinks = [];

      $(".yuRUbf > a > h3").each((i, el) => {
        titles[i] = $(el).text();
      });
      $(".yuRUbf > a").each((i, el) => {
        links[i] = $(el).attr("href");
      });
      $(".g .VwiC3b ").each((i, el) => {
        snippets[i] = $(el).text();
      });
      $(".g .yuRUbf .NJjxre .tjvcx").each((i, el) => {
        displayedLinks[i] = $(el).text();
      });

      const organicResults = [];

      for (let i = 0; i < titles.length; i++) {
        organicResults[i] = {
          title: titles[i],
          links: links[i],
          snippet: snippets[i],
          displayedLink: displayedLinks[i],
        };
      }
      console.log(organicResults)
    });
};

getOrganicData();

I’m trying to write a function that will successfully scrape the first few links of a google search (for example, I can pass through the query “Javascript” and I want to get the first few results when that term is searched).

I found this blog https://serpdog.io/blog/scrape-google-search-results/ and followed it.
I ran the code on the website and it returned a blank array []. (I am using node js)
I attached the code, but it’s exactly the same as on the blog.

Any ideas on how to fix this? Or do you have a better way to get the first few search results from a search term?

Thanks!

I tried several different methods of getting the top search results, none of which worked.

My app is unable to write a docx file after being converted into a .exe file

I’ve written a simple program in Node.js / electron that reads an excel spreadsheet and then writes the data onto a docx template and creates a new docx file with when done. When I run my program with npm start it works perfectly but once I converted it into an exe file it is unable to do this function and i dont know why? The program will open and take me to the landing page i designed but these functions do not run. please help. thanks!

I’ve tried changing the permissions on the exe file to allow it access to read and write but that didnt work.

Mobile view toggles class but do not change element

I’ve searched a lot about this issue, however is slightly different from the others. Most of posts here relates to “toggle not working”, but mine toggle works, the problem is that it doesn’t change the view, it doesn’t open/close element.

Check the snippet below, you’ll see that does work on desktop but does not in mobile view.

Is there any special JS rule to make it works in mobile browsers or something related to touch screens? How to make it work?

  function toggleForm(event) {
    console.log("clicked");

    var form = document.getElementById('search-form');
    form.classList.toggle('hidden-form');

    console.log(form.classList);
  }
.hidden-form {
    display: none !important;
    height: auto !important;
}
<div onclick="toggleForm()" id="toggleButton">
  <h3>TITLE</h3>
</div>

<form action="#" id="search-form" class="hidden-form">
  TEXT
</form>

javascript onclick event, add +1 and -1 in quantity product

I tried to make a code with Jquery when I click the + button, the field quantity increases, and when I press the – button the quantity decreases, and it works

but when I press another color and size, the field jumps no longer +1
do +2

first round work

second round jump

However, this method still doesn’t work for me. Can anyone help? Thank you.

$('#partQuantity').on('click', "#plus" + data[k].Id, function(event) {
    event.preventDefault();
    var quantityInput = document.getElementById('qua' + data[k].SkuSizeId); // Assuming 'SkuSizeId' is the correct property
                                            
    if (quantityInput) {
        var currentValue = parseInt(quantityInput.value) || 1;

        if (currentValue < data[k].OnHand) {
            quantityInput.value = currentValue + 1;
        }
    } 
});
                                   
                                    

                                    
  $('#partQuantity').on('click', "#minus" + data[k].Id, function(event) {
event.preventDefault();

var quantityInput = document.getElementById('qua' + data[k].SkuSizeId); // Assuming 'SkuSizeId' is the correct property


var currentValue = parseInt(quantityInput.value);
if (currentValue > 1) {
    quantityInput.value = currentValue - 1;
 }

});

Android Webview touch event not trigged in iframe

This is an android project and I need to load a website in a webview.
And one more request here is the website needs to be loaded in a iframe.

This is done by the following step:

  1. create a webview
  2. I have a sample html file
  3. I load my sample html file
  4. I call wewbview.loadHTMLString(sampleHtmlString, "") to load the site from string;

Sample html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
    </style>
</head>
<body>
    <script>
        document.addEventListener('touchstart', function(event) {
            console.log("document touchstart");
        });
    </script>
</body>
</html>

And webview show all good on device also i can see touch event triggered.


Then I will add the iframe part:

  1. User input a url to load for example: “https://www.facebook.com”
  2. Still I load my sample html file
  3. Then I replace the PLACE HOLDER in sample file to the one user input for example: "https://www.facebook.com"
  4. Then call wewbview.loadHTMLString(sampleHtmlString, "");

Updated sample html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        .webview-container {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            overflow: hidden;
        }
        iframe {
            width: 100%;
            height: 100%;
            border: none;
        }
    </style>
</head>
<body>
    <div class="webview-container" id="webview-container">
    </div>
    <script>
        function loadWebView(url) {
            var iframe = document.createElement('iframe');
            iframe.src = url;
            document.getElementById('webview-container').innerHTML = '';
            document.getElementById('webview-container').appendChild(iframe);
            iframe.onload = function() {
                console.log("iframe onload");
            };
        }

        document.addEventListener('touchstart', function(event) {
            console.log("document touchstart");
        });
        loadWebView('https://www.example.com');
    </script>
</body>
</html>

I can see the site loaded in iframe correctly but this time touchstart not trigggered when touched.

I searched few posts then tried:

function loadWebView(url) {
    var iframe = document.createElement('iframe');
    iframe.src = url;
    document.getElementById('webview-container').innerHTML = '';
    document.getElementById('webview-container').appendChild(iframe);
    iframe.onload = function() {
        console.log("iframe onload");
        iframe.contentWindow.document.addEventListener('touchstart', function(event) {
            console.log("iframe touchstart");
        });
    };
}

But still not working and I am getting the error in console:



Uncaught SecurityError: Failed to read a named property 'document' from 'Window': 
Blocked a frame with origin "null" from accessing a frame with origin 
"https://www.grandbrowser.com".  

The frame requesting access has a protocol of "about", 
the frame being accessed has a protocol of "https". 
Protocols must match.", source: about:blank (41)

I also tried to remove the "https:" from the url according to this post:

The frame requesting access has a protocol of “https”, the frame being accessed has a protocol of “http”. Protocols must match

But then the error in console is gone but the site will not load anymore.


Any advice on this issue will be appreciated, thanks in advance.

How can I achieve this with html and css?

I am creating a portfolio website for myself but i am a beginner in web dev. I wanted to create a section in my page at the bottom where the “start a project” box in the picture will be my about section and rest will be used as my footer for links and copyrights.enter image description here

It looks like this currently. i just need a background that is underneath the about section and starts from middle to the bottom and no margins for the background.

<section id="about">
    <div class="abt-content">
        <h2 class="abt-title">About Me 
            <i class="fa-regular fa-lightbulb"></i>
        </h2>
        <p class="abt-desc"></p>
    
</div>
</section>
#about {
    margin-left: 70px;
    margin-right: 5%;
    margin-bottom: 20%;
    padding: 80px 0px;
}

.abt-content {
    background-color: #232946;
    padding: 50px 0px;
    box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.25);
    border-radius: 12px;

}

.abt-title {
    color: #fffffe;
    text-align: center;
    margin-bottom: 10px;
    font-family: montserrat, Verdana, Geneva, Tahoma, sans-serif;
    font-size: 35px;
    font-weight: 700;
}[enter image description here](https://i.stack.imgur.com/dUTIz.png)

Drilldown packed bubble chart to scatter plot not rendering in Highcharts

I have a packed bubble chart, and I want to drill down the bubbles to a scatter plot. Also as a bonus would love to be able to drill down the main bubble to a scatter plot which is a mix of all of the scatter plots, I am not sure if that is possible.

I am building this code using React. Right now. On drill down, the scatter plot is not rendering.

My code: component.js

import React, { useEffect, useState } from "react";
import { Spinner } from "react-bootstrap";
import "bootstrap/dist/css/bootstrap.min.css";
import ScatterChart from "./scatter";
import "./App.css";

const ScatterComponent = ({ data, filteredData }) => {
  const [loading, setLoading] = useState(true);
  const chartData = filteredData.length !== 0 ? filteredData : data;

  const bubbleSeries = [{"name":"ABC","data":[{"name":"page_views","value":6652301,
  "drilldown":"ABC - page_views"},{"name":"article_views","value":4812992,"drilldown":"ABC - article_views"},
  {"name":"visits","value":5116176,"drilldown":"ABC - visits"},]},
  {"name":"XYZ","data":[{"name":"page_views","value":16448241,"drilldown":"XYZ - page_views"},
  {"name":"article_views","value":10791478,"drilldown":"XYZ - article_views"},
  {"name":"visits","value":11921915,"drilldown":"XYZ - visits"},]}];

  const scatterSeries = [{"type":"scatter","id":"ABC - page_views",
  "data":[["2024-02-27T00:00:00.000Z",1],["2024-02-26T00:00:00.000Z",1],["2024-02-27T00:00:00.000Z",1],["2024-02-28T00:00:00.000Z",1]],},
  {"type":"scatter","id":"ABC - article_views",
  "data":[["2024-02-27T00:00:00.000Z",1],["2024-02-26T00:00:00.000Z",1],["2024-02-27T00:00:00.000Z",1],["2024-02-28T00:00:00.000Z",1]],},
  {"type":"scatter","id":"ABC - visits",
  "data":[["2024-02-27T00:00:00.000Z",1],["2024-02-26T00:00:00.000Z",1],["2024-02-27T00:00:00.000Z",1],["2024-02-28T00:00:00.000Z",1]],},
  {"type":"scatter","id":"XYZ - page_views",
  "data":[["2024-02-27T00:00:00.000Z",1],["2024-02-26T00:00:00.000Z",1],["2024-02-27T00:00:00.000Z",1],["2024-02-28T00:00:00.000Z",1]],},
  {"type":"scatter","id":"XYZ - article_views",
  "data":[["2024-02-27T00:00:00.000Z",1],["2024-02-26T00:00:00.000Z",1],["2024-02-27T00:00:00.000Z",1],["2024-02-28T00:00:00.000Z",1]],},
  {"type":"scatter","id":"XYZ - visits",
  "data":[["2024-02-27T00:00:00.000Z",1],["2024-02-26T00:00:00.000Z",1],["2024-02-27T00:00:00.000Z",1],["2024-02-28T00:00:00.000Z",1]],},
]
  


  useEffect(() => {
    const delay = setTimeout(() => {
      setLoading(false);
    }, 2000);

    return () => clearTimeout(delay);
  }, []);

  return (
    <div className="bubbleScatterTrends clearfix w-100 column">
      <h3 className="mt-1 ms-1" style={{ color: "#81b0d2" }}>
        <u>ABC-XYZ Breakdowns</u>
      </h3>
      {loading ? (
        <div className="text-center">
          <Spinner animation="border" variant="primary" />
          <Spinner animation="border" variant="secondary" />
          <Spinner animation="border" variant="success" />
          <Spinner animation="border" variant="danger" />
          <Spinner animation="border" variant="warning" />
          <Spinner animation="border" variant="info" />
          <Spinner animation="border" variant="light" />
          <Spinner animation="border" variant="dark" />
        </div>
      ) : (
        <div className="clearfix w-100 column">
          <div className="clearfix w-100 column">
            <div className="w-100 bubbleScatterCharts">
              <ScatterChart
                bubbleData={bubbleSeries}
                scatterData={scatterSeries}
              />
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

export default ScatterComponent;

scatter.js

import React, { useMemo } from "react";
import Highcharts from "highcharts";
import HighchartsReact from "highcharts-react-official";
import highchartsAccessibility from "highcharts/modules/accessibility";
import highchartsExporting from "highcharts/modules/exporting";
import highchartsExportData from "highcharts/modules/export-data";
import highchartsPackedbubble from "highcharts/highcharts-more";
import dayjs from "dayjs";
import "dayjs/locale/es";

highchartsAccessibility(Highcharts);
highchartsExporting(Highcharts);
highchartsExportData(Highcharts);
highchartsPackedbubble(Highcharts);

const ScatterChart = ({ bubbleData, scatterData }) => {
  dayjs.locale("en");
  const addCommas = (x) =>
    x.toString().replace(/B(?<!.d*)(?=(d{3})+(?!d))/g, ",");

  const options = useMemo(
    () => ({
      chart: {
        type: "packedbubble",
        backgroundColor: "#283347",
      },
      exporting: {
        enabled: true,
      },
      navigation: {
        buttonOptions: {
          verticalAlign: "top",
          y: -10,
          x: -5,
        },
      },
      accessibility: {
        enabled: false,
      },
      credits: {
        enabled: false,
      },
      legend: {
        enabled: true,
        itemStyle: {
          color: "#fff",
        },
      },
      tooltip: {
        backgroundColor: "#283347",
        style: { color: "#fff" },
        formatter: function () {
          if (this.y !== undefined || this.key !== undefined) {
            let tooltip = `<span><b><u>${this.key}</u></b>: ${addCommas(
              this.y
            )}</span>`;
            return tooltip;
          }
        },
        useHTML: true,
      },
      plotOptions: {
        packedbubble: {
          minSize: "20%",
          maxSize: "100%",
          zMin: 0,
          zMax: 1000,
          layoutAlgorithm: {
            gravitationalConstant: 0.05,
            splitSeries: true,
            seriesInteraction: false,
            dragBetweenSeries: true,
            parentNodeLimit: true,
          },
          dataLabels: {
            enabled: true,
            format: "{point.name}",
            filter: {
              property: "y",
              operator: ">",
              value: 250,
            },
            style: {
              color: "black",
              textOutline: "none",
              fontWeight: "normal",
            },
          },
        },
      },
      series: bubbleData,
      drilldown: {
        series: scatterData,
      },
    }),
    [bubbleData, scatterData]
  );

  return <HighchartsReact highcharts={Highcharts} options={options} />;
};

export default ScatterChart;

My scatter plot is not rendering.

scatterplot

Javascript – Bind Class Methods to Proxy Object

I am using the Javascript Proxy system to allow individual functions to subscribe to any changes in an object defined by a class. For example purposes, say this is my code:

class Data {
    i = 0
    increment() {
        this.i++;
    }
}

const obj = new Data();
const objProxy = new Proxy(obj {
    get: function(target, prop) {
        return Reflect.get(target, prop, objProxy);
    },
    set: function(target, prop, value) {
        console.log("setting", prop, "of", target);
        return Reflect.set(target, prop, value, objProxy);
    }
}

objProxy.increment();

The issue is that the this reference in the increment function is a reference to the object itself, not the proxy, so the proxy setter doesn’t seem to be triggered.

I tried to specify the object proxy as the “receiver” option for both the getter and the setter, expecting that the “this” reference would be changed to the proxy and the log message would be triggered when “i” is changed.

Moving to Node as a FrontEnd

I am a FrontEnd engineer with more than 10 years of experience,
Recently I found out that market has been changing and now a full stack is more required than before (or at least the FE should know in a proficient way a BE Language) so I decided to move to node as the learning curve will be easier.

  • Any recommendations to become a proficient Node JS developer? Should
  • I learn a DB such as mongo or is it better a relational kind of BD?
  • which framework should I learn? Node or Nest
  • which things should I avoid in order to truly understand the node
    philosophy.

Thanks!

Trouble accessing JSON object as a Constant in a Javascript Module

I have Javascript module named constants.js with the following in it:

const coreObjects = {
    activity: {
        objectName: 'activity',
        table: 'activities',
        pk: 'activity_id',
        recordTypeID: 'A'
    }
}
export { coreObjects }

I’m trying to reference the ‘table’ attribute of this constant with the following in a separate script file:

let constants = await import('./constants.js');
let actvityTable = constants.coreObjects.activity.table;

And I get the following error:

TypeError: Cannot read properties of undefined (reading 'activity')

Any thoughts on how I get this to work? Thanks!

When I change to the following it doesn’t generate an error but is not giving me the specific access to the ‘table’ field that I was looking for:

let actvityTable = constants.coreObjects

No Updated Review When Submit is Clicked

I’m reworking a program I worked on last week to take data from an API and need to update the reviews by using PUT, however, the form section is giving my issues. When I click on the Submit button the user’s review is supposed to render onto the app, but when Submit is clicked nothing happens.

So far the code I have uses PUT but I have POST as well. I’m not sure which would be better to use, what should I be using to add data to the API?

Here is the code I have so far for the App component:

App Component:

import './App.css';
import React, { useState, useEffect } from 'react';

import ToDoForm from './ToDoForm';
import ToDoList from './ToDoList';
import { fetchAPI } from './utils';

const URL = 'https://api-server-xki8.onrender.com/todos';

function App() {
  const [todos, setStoreToDos] = useState([]);

  useEffect(() => {
    let options = {
      method: 'GET',
      headers: { 'Content-Type': 'application/json' },
    };

    async function fetchData() {
      try {
        const todosData = await fetchAPI(URL, options);
        todosData.sort((a, b) => (a.id < b.id) ? 1 : -1);
        setStoreToDos(todosData);
      } catch (error) {
        console.error('Error fetching data!', error.message);
        setError('Error setting data. Please try again later.');
      }
    }

    fetchData();
  }, []);

  const addToDos = async (val) => {
    const newToDoItems = {
      text: val,
      isCompleted: false,
    };

    let options = {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },

      body: JSON.stringify(newToDoItems),
    };

    try {
      const newTodo = await fetchAPI(URL, options);
      const newToDos = [...todos, newTodo].sort((a, b) =>
       (a.id < b.id) ? 1 : -1
      );

      setStoreToDos(newToDos);
    } catch (error) {
      console.error('Error:', error.message);
    }
  };

  const completeToDo = async (id) => {
    const tempToDos = [...todos];
    const index = tempToDos.findIndex((todos) => todos.id === id);
    tempToDos[index].isCompleted = !tempToDos[index].isCompleted;

    const updatedToDo = {
      text: tempToDos[index].text,
      isCompleted: tempToDos[index].isCompleted
    };

    let options = {
      method: 'PUT',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(updatedToDo)
    };

    try {
      await fetch(`${URL}/${id}`, options);

      setStoreToDos(tempToDos);
    } catch (error) {
      console.error('Error:', error.message);
    }
  };

  const deleteToDos = async (id) => {
    let options = {
      method: 'DELETE'
    };

    try {
      const resDelete = await fetch(`${URL}/${id}`, options);

      if (!resDelete.ok) {
        throw new Error('DELETE failed!');
      }
      const res = await fetch(URL);
      const data = await res.json();

      setStoreToDos(data);
    } catch (error) {
      console.error('Error:', error.message);
    }
  };

  const editToDos = async (id, text) => {
    try {
      const temporaryToDos = [...todos];
      const index = temporaryToDos.findIndex((todo) => todo.id === id);
      temporaryToDos[index].text = text;

      const updatedToDo = {
        text,
        isCompleted: temporaryToDos[index].isCompleted
      };

      let options = {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(updatedToDo)
      };
      await fetch(`${URL}/${id}`, options);

      setStoreToDos(temporaryToDos);
    } catch (error) {
      console.error('Error', error.message);
    }
  };

  // console.log("App is Rendering");

  return (
    <>
      <h2>To Do App</h2>
      <h5>Add New To Do Items via the Input Field: </h5>
      <ToDoForm addToDos={addToDos} />

      <ToDoList
        todos={todos}
        completeToDo={completeToDo}
        deleteToDos={deleteToDos}
        editToDos={editToDos}
      />
    </>
  );
}
export default App;

import React, { useState} from 'react';
// import { fetchAPI } from './utils';

import StarRating from './StarRating.jsx';

function UserRating({ movieID,   onUpdateReview}) {
  const [user, setUser] = useState('');
  const [review, setReviews] = useState('');
  const [stars, setStars] = useState(0);

  
  
  const handleUser = (e) => {
    setUser(e.target.value);
  };

  const handleReview = (e) => {
    setReviews(e.target.value);
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    


    const addReview = ({ 
      movieID,
     user: user, 
     review: review, 
     rating: stars
  }
)
  
    onUpdateReview(addReview)
    
    formReset();
    
  };

  
  
  const formReset = () => {
    setUser('');
    setReviews('');
    setStars(0);
  };

  return (
    <div className="userReview">
      <form onSubmit={handleSubmit} >
        
        <h2>Rate This Movie:</h2>
        <label>
          <label>
            Name:
            <input
              type="text"
              value={user}
              onChange={handleUser}
              required
              placeholder={'Enter Name Here:'}
            />
          </label>

          <label>
            Review:
            <textarea
              value={review}
              onChange={handleReview}
              required
              placeholder={'Enter Review Here:'}
              rows={8}
              cols={39}
            ></textarea>
          </label>
        </label>

        <StarRating disabled={false} stars={stars} set={setStars} />

        <button type="submit" value="Submit">
          Submit {''}
        </button>
      </form>
    </div>
  );
  
}

export default UserRating;

So far, I’ve tried using PUT and have a function in the UserRating component to submit data. I’ve tried different variations of the value tempMovies[index] including using tempMovies[index].user = user, tempMovies[index].user = !tempMovies[index].user. I had also tried to make a useState in UserRating that would set the values of the form into the handleSubmit function, but it causes the program to crash.