How do you generate static pages that read local data in a NextJS 13 application?

I completed their blog tutorial, and it works fine. It creates dynamic pages from .md blog posts that are stored locally. Beautiful.

But I am running into a wall trying to make what seems like a simple modification.

I want to add search and filter to the blog posts. For that, we need to “use client”. And the fs module does not work on the client. Their docs recommend using the fetch API, but that doesn’t work on local files, as they aren’t URLs.getStaticProps() is deprecated when using the /app router, I believe in older versions I could have run that, and run my fs functions at build time

This is one of the two functions that need to run.

export async function getPostData(id: string) {
  const fullPath = path.join(process.cwd(), `/public/posts/${id}.md`);
  const fileContents = fs.readFileSync(fullPath, "utf8");


  // Use gray-matter to parse the post metadata section
  const matterResult = matter(fileContents);

  const processedContent = await remark()
    .use(html)
    .process(matterResult.content);

  const contentHtml = processedContent.toString();

  const blogPostWithHTML: BlogPost & { contentHtml: string } = {
    id,
    title: matterResult.data.title,
    date: matterResult.data.date,
    tags: matterResult.data.tags,
    contentHtml,
  };
  // Combine the data with the id
  return blogPostWithHTML;
}

So I believe I either need to run these functions at build time, to generate static pages for each blog post (there’s only 2). Or I need some client side way to read local files. That would be as simple as ANYTHING that can turn a .md into a string!

(I cannot do SSR, as I am generating the whole site statically, and simply hosting it on S3 with a cloudfront distribution)

Javascript and JSON Caching Issue

I have the following code that is performing the following functions:

  • The PHP section reads the CSV file and converts its data into an
    array.
  • The table is constructed using HTML and PHP loops to display
    the CSV data.
  • Each row in the table has an “Import Risk” button and a
    “Refresh” button.
  • The “Import Risk” button triggers an AJAX request to the ajax-import.php file, sending the JSON data associated with the row.
  • The response from ajax-import.php is parsed, and if successful, the table row is updated with the risk information or error messages.
  • The JSON data for each row is stored
    as the data-json attribute of the “Import Risk” button.
  • The “Refresh” button triggers an AJAX request to the refresh.php file, which
    retrieves the latest data for the row. The table row is updated with
    the refreshed data.

There is an issue that persists and can’t seem to get to the bottom of – the issue appears only after the “Import” button is clicked. The data-json is refreshed (when I click the “Refresh” button), but JSON being sent to ajax-import.php appears to be the initial version of that was sent when the import button was clicked.

The intended outcome is to be able to refresh the data-json anytime the “Refresh” button is clicked and that updated JSON is what should be sent to the ajax.import.php script for processing.


<!-- Start Table Content -->
            <div class="row">
                <div class="col-12">
                    <div class="card">
                        <div class="card-body">
                            <h2>CSV File Contents</h2>

                            <?php $csvtoarray_clean = sanitize_csv_file($file_path); ?>

                            <?php  // Convert the CSV data to an array
                            $csvtoarray = array_map('str_getcsv', explode("n", $csvtoarray_clean));
                            ?>

                            <div class="table-responsive">
                                <table class="table table-bordered">
                                    <thead>
                                        <tr>
                                            <th>#</th>
                                            <?php foreach($csvtoarray[0] as $col): ?>
                                                <th><?= htmlspecialchars($col) ?></th>
                                            <?php endforeach; ?>
                                            <th>JSON Output</th>
                                            <th>Actions</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        <?php for($i=1; $i<count($csvtoarray); $i++): ?>

                                            <tr>
                                                <td><?= $i; ?></td>
                                                <?php foreach($csvtoarray[$i] as $cell): ?>
                                                    <td><?= htmlspecialchars($cell) ?></td>
                                                <?php endforeach; ?>

                                                <?php $json_data = processJson(json_encode(array_combine($csvtoarray[0], $csvtoarray[$i])),$file_ref); ?>
                                                <td style="min-width: 550px;">
                                                    <code>    
                                                        <?php echo removeEmptyValues($json_data);?>
                                                        <?php $validation_response = json_decode($json_data, true); ?>
                                                    </code>
                                                </td>
                                                
                                                <td class="response-col">
                                                    <?php if ($validation_response['status'] == 'error'): ?>
                                                        <strong>There are errors on this row of data:</strong>
                                                        <?php foreach ($validation_response['errors'] as $error): ?>
                                                            <li><?= htmlspecialchars($error) ?></li>
                                                            <button class="refresh-btn btn btn-secondary" data-row="<?= $i ?>" data-hash="<?= md5(serialize($csvtoarray[$i])) ?>">Refresh</button>
                                                        <?php endforeach; ?>
                                                    <?php else: ?>
                                                        <div class="alert alert-danger" role="alert" style="display: none;"></div>
                                                        <div class="btn-group" role="group" aria-label="Actions">
                                                            <button class="import-button btn btn-primary" data-row="<?= $i ?>" data-json="<?php echo htmlspecialchars(removeEmptyValues($json_data)) ?>">Import Risk</button>
                                                            <button class="refresh-btn btn btn-secondary" data-row="<?= $i ?>" data-hash="<?= md5(serialize($csvtoarray[$i])) ?>">Refresh</button>
                                                        </div>
                                                    <?php endif; ?>
                                                </td>
                                            </tr>
                                        <?php endfor; ?>
                                    </tbody>
                                </table>
                            </div>
                        </div>
                    </div>                
                </div>
            </div>
            <!-- End Table Contents -->

            <script>
                $(document).ready(function() {
                    // Handle import button click
                    $(document).on('click', '.import-button', function() {
                        var json_data = $(this).data('json');

                        var button = $(this);
                        var alert = button.closest('tr').find('.alert');
                        alert.hide();

                        $.ajax({
                        type: 'POST',
                        url: 'ajax-import.php?cache=' + new Date().getTime(), // Add cache-busting parameter to the URL
                        data: {
                            json_data: button.data('json'), // Fetch the latest data-json value from the button
                            cacheBuster: new Date().getTime() // Cache-busting parameter
                        },
                        beforeSend: function(xhr) {
                            xhr.setRequestHeader('Cache-Control', 'no-cache');
                        },
                        success: function(response) {
                            try {
                            var data = JSON.parse(response);

                            var risk_number = data.result.riskNumber;
                            var risk_url = data.result.riskURL;
                            var status = data.result.status;
                            var responseText = data.result.responseText;
                            var errorText = data.result.errorText;

                            if (risk_url !== undefined) {
                                button.closest('tr').find('.response-col').html('<a href="' + risk_url + '" class="btn btn-primary" target="_blank">' + risk_number + '</a>');
                            } else {
                                var alertContent = '<h4 class="alert-heading">' + responseText + '</h4>' + errorText;
                                alert.html(alertContent);
                                alert.show();
                            }

                            // Log the data being sent to the import script
                            console.log('Import Data:', button.data('json')); // Log the latest data-json value

                            // Refresh the data in the table row
                            updateDataAndDOM(button, response);
                            } catch (error) {
                            console.error('Error parsing JSON:', error);
                            }
                        },
                        error: function(xhr, status, error) {
                            var errorMessage = 'Error: ' + error;
                            alert.html(errorMessage);
                            alert.show();

                            button.text('Failed');
                            button.addClass('btn-danger');
                        }
                        });
                    });

                    // Function to update JSON data and DOM elements
                    function updateDataAndDOM(refreshButton, refreshedData) {
                        var row = refreshButton.data('row');

                        var refreshedRowData = JSON.parse(refreshedData);
                        var rowDataElements = refreshButton.closest('tr').find('td:not(.response-col)');
                        rowDataElements.each(function(index) {
                        var header = $(this).closest('table').find('th').eq(index).text();
                        var newData = refreshedRowData[header];
                        if (newData !== undefined) {
                            $(this).text(newData);
                        }
                        });

                        importButton = refreshButton.closest('tr').find('.import-button[data-row="' + row + '"]');
                        importButton.attr('data-json', refreshedData); // Update the data-json attribute
                    }

                    // Handle refresh button click
                    $(document).on('click', '.refresh-btn', function() {
                        var refreshButton = $(this);
                        var row = refreshButton.data('row');
                        var hash = refreshButton.data('hash');

                        $.ajax({
                        url: 'refresh.php',
                        data: {
                            row: row,
                            hash: hash,
                            csvFilePath: '<?php echo $file_path; ?>',
                            timestamp: new Date().getTime() // Append timestamp as a parameter
                        },
                        type: 'GET',
                        dataType: 'json',
                        success: function(response) {
                            if (response.status === 'refreshed') {
                            var refreshedData_raw = response.refreshed_data;
                            var refreshedData = JSON.stringify(refreshedData_raw);
                            console.log('Refreshed Data:', refreshedData_raw);

                            updateDataAndDOM(refreshButton, refreshedData);
                            } else {
                            console.log(response.message);

                            var emptyData = '{}';
                            updateDataAndDOM(refreshButton, emptyData);
                            }
                        },
                        error: function(xhr, status, error) {
                            console.log('Error: ' + error);

                            var emptyData = '{}';
                            updateDataAndDOM(refreshButton, emptyData);
                        }
                        });
                    });
                });
            </script>

Automated Serial Terminal from HHD – Anyone Familiar?

I need to write some scripts to repeatedly send some data via RS-232 to a device. I downloaded (and paid for) this Automated Serial Terminal program, but the documentation seems to be a bit lacking (and/or my knowledge of object-based programming and JS is lacking).

As a simple test, I am trying to send one hex byte over and over with a short delay between:

var session = terminal.createSession("COM9", { baudRate: 57600, dataBits: 8, stopBits: 1, 
    parity: Terminal.Parity.None, flowControl: flowControl.none }, false);
    
session.start

let B0 = 0xA1

while(1)
{
    session.send(B0)
    delay(20)
}

session.stop

I have a USB-to-RS232 adapter on COM9. This compiles without error, but instead of sending that byte repeatedly, it doesn’t send anything, and the entire program closes and restarts.I’m not sure if I’m doing something wrong or there’s a bug.

Anyone familiar with it?

Setting Default Value for Dynamic Dropdown Options in Angular FormProp

I have the following FormProp constant as:

const timeZoneProp = new FormProp<IdentityUserDto>({
    type: ePropType.Enum,
    name: 'TimeZoneId',
    displayName: '::TimeZone',
    isExtra: true,
    id: 'TimeZoneId',
    autocomplete: 'off',
    validators: () => [Validators.required],
    options: (data: PropData<IdentityUserDto>): Observable<Option<any>[]> => {
      const service = data.getInjected(TimeZoneService);
      return service
        .getList()
        .pipe(
          map(
            response =>
              response.items?.map(
                item =>
                  ({ key: item.description, value: item.id } as Option<any>)
              ) || []
          )
        );
    }
  });

This is working correctly; now I want to set a default value to that prop. This FormProp has a property: defaultValue:

readonly defaultValue: boolean | number | string | Date;

But the default value will not work because it needs data from the options prop. So I want the default value prop to be a promise of the code inside the options prop that got resolved under the constructor. So I try:

const timeZoneProp = new FormProp<IdentityUserDto>({
    type: ePropType.Enum,
    name: 'TimeZoneId',
    displayName: '::TimeZone',
    isExtra: true,
    id: 'TimeZoneId',
    autocomplete: 'off',
    defaultValue: new Promise(resolve => {
      const data = {}; 
      const optionsPromise = this.options(data).toPromise();

      optionsPromise.then(options => {
        if (options.length > 0) {
          resolve(options[0].value);
        } else {
          resolve(null); // Set default value to null if options array is empty
        }
      });
    }).then(
      resolvedValue =>
        resolvedValue as string | number | boolean | Date | undefined
    ), // Cast the resolved value to the appropriate type
    validators: () => [Validators.required],
    options: (data: PropData<IdentityUserDto>): Observable<Option<any>[]> => {
      const service = data.getInjected(TimeZoneService);
      return service
        .getList()
        .pipe(
          map(
            response =>
              response.items?.map(
                item =>
                  ({ key: item.description, value: item.id } as Option<any>)
              ) || []
          )
        );
    }
  });

But this throws an error in the defaultValue prop.

Type ‘Promise<string | number | boolean | Date | undefined>’ is not
assignable to type ‘string | number | boolean | Date |
undefined’.ts(2322) form-props.d.ts(36, 14): The expected type comes
from property ‘defaultValue’ which is declared here on type ‘{
validators?: PropCallback<IdentityUserDto, ValidatorFn[]> | undefined;
asyncValidators?: PropCallback<IdentityUserDto, AsyncValidatorFn[]> |
undefined; … 15 more …; name: string; }’ (property) defaultValue?:
string | number | boolean | Date | undefined

and the line const optionsPromise = this.options(data).toPromise(); throw

this' implicitly has type 'any' because it does not have a type annotation.

How can I achieve this?

Failed to resolve a module in vanilla js with Vite

I’m encountering an issue while trying to import npm package in my Vite project. I have followed the recommended approaches, but I keep receiving the error message in my site console:

"TypeError: Failed to resolve module specifier 'axios'. Relative references must start with either '/', './', or '../'." 

I’ve tried to find information by myself, or use ChatGPT, but both tries failed

Here is my Repository where you can get acquainted with the directory structure and files


I’ve tried the following steps with Axios package as for example to check whether error occurs or not:

– Installed Axios using

npm install axios

– Updated the vite.config.js file with the resolve alias configuration:

import { defineConfig } from 'vite';

export default defineConfig({
    resolve: {
        alias: {
            'axios': 'axios'
        }
    },
    server: {
        proxy: {
            '/api': {
                target: 'http://localhost:3000',
                changeOrigin: true,
                rewrite: (path) => path.replace(/^/api/, '')
            }
        }
    },
    optimizeDeps: {
        include: [
            'axios'
        ]
    }
});

– Used the import statement in my index.js file:

import axios from 'axios';

Despite these steps, I’m still facing the error mentioned above. Any insights or suggestions on resolving this issue would be greatly appreciated.

input field doesnt clear on single click of delete button, only double

I am using formik and I have a textfield where user inputs SSN number. I have a function handling the format of SSN number to something like this 000-00-0000. I call this function in my onChange and this works well. But the problem is when i try to clear the input field, it takes two clicks to delete one number

const [ssn, setSsn] = useState('');

const normalizeInput = (value: any, previousValue: any) => {
    // return nothing if no value
    if (!value) return value;

    // only allows 0-9 inputs
    const currentValue = value.replace(/[^d]/g, '');
    const cvLength = currentValue.length;

    if (!previousValue || value.length > previousValue.length) {
      // returns: "1", "12", "123"
      if (cvLength < 4) return currentValue;
      // returns: "123", "123-4", "123-45",
      if (cvLength < 7) return `${currentValue.slice(0, 3)}-${currentValue.slice(3)}`;
      // returns: "123-45-", "123-45-6", "123-45-67", "123-45-678", "123-45-6789"
      return `${currentValue.slice(0, 3)}-${currentValue.slice(3, 5)}-${currentValue.slice(5, 9)}`;
    }
  };
<form onSubmit={formik.handleSubmit}>
          <TextField
            name="ssn"
            id="ssn"
            label="SSN*"
            variant="filled"
            value={formik.values.ssn}
            onChange={(e) => {
              setSsn(normalizeInput(e.target.value, ssn));
            }}
          />
        </form>

Making text change for three different things JS and CSS

I need some text to change (with a 1 second interval) on my website. (https://website.elliott23.repl.co). I can’t figure out how to make it routinely change with an interval of 1 second. This is my javascript for it.

var $text = $("#text");
var numbers = ["First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth"];

for (var i = 1; i <= 10; ++i) {
  (function(index) {
    setTimeout(function() { 
      $text.html(numbers[index-1] + " sentence");
    }, i * 1000);
  })(i);
}

This is my HTML

<div id="text"></div>

The text isn’t changing. This is the html all around the element that needs to change.

<div class="opening">
    <h1>Hey, I'm<span class="green-text"> Elliott D'Orazio</span><br></h1>
      <h1>I design and develop<span class="italic"></span><div id="text"></div></h1>
</div>

I tried already checking on stack overflow. None of the articles helped me do what I needed to do. The code I provided above is from another stack post. I have no clue how to do this as my JavaScript knowledge is less than my HTML and CSS.

inline event handlers inside JS file

Is it a good practice to pass inline event handler to html element when creating that element inside JS file?

I knew that it is not a good practice to do that inside html file because of the ‘Separation of concerns’ principle, but when doing that inside JS file it is not a violation for that principle any more is it?


let htmlElement = `<button onclick="functionName()"></button>`

function functionName() {
  alert('hello');
}

Is html element’s line break value always normalized to “n” javascript string?

Having a Windows system, I found out that a textarea value consisting of one single line break is equal to the JavaScript string "n", and not "rn":

console.log(document.getElementById("textarea").value === "n"); // true
console.log(document.getElementById("textarea").value === "rn"); //false
<textarea name="" id="textarea" cols="30" rows="10">

</textarea>

Does it mean I should not worry about the CRLF vs LF issue while working with HTML elements’ values as their line breaks always normalized to the "n" === "u{000A}" string, so I can surely say that lineBreakOnlyValue.length === 1 and fulfill such an assignment
document.getElementById("textarea").value = "n" without thoughts about different systems line breaking addressing?

Was this behavior specificated in some way?

What is the URI “places:” schema in “Places query URIs” in Web API / browsers?

I saw some old (2014) StackOverflow answer mentioning the term “Places query URIs”, providing a broken link to Mozilla’s MDN.

I tried to

  • search Google for the “places:” schema
  • explore the modern “Location” API, trying to find some clues

All I could find is a mysterious cached/archived version of the possibly original old webpage from MDN, and another archived webpage explaining the Places thing. It’s from at least 2016, and claims that:

Places is the bookmarks and history management system introduced in Firefox 3. It offers increased flexibility and complex querying to make handling the places the user goes easier and more convenient. It also includes new features including favicon storage and the ability to annotate pages with arbitrary information. It also introduces new user interfaces for managing all this information; see Places on the Mozilla wiki.

Places stores its data in an SQLite database using the mozStorage interfaces.

2016 is so before the Common Era? No one uses this API? no browser supports it? Even no one documents it as a deprecated feature? no backward-compatibility?

What’s the straightforward alternative to it?

What was the exact goal of it? Why it’s gone?

My goal was to manipulate the session history, trying to learn the possible capabilities beyond “History” API

My video wont stop playing when i stop hovering on the thumb nail

I tried making a thumbnail to play a YouTube video when I hover and stop playing when I stop hovering on it, but it doesn’t stop when the mouse isn’t hovering on it.
Here’s the code:

<div class="thumbnail" data-video-id="D9N7QaIOkG8">
    <img src="assetsmeyra.jpg" alt="Thumbnail 1">
    <div class="video-overlay"></div>
</div>

<script>
  function onYouTubeIframeAPIReady() {
    const thumbnails = document.querySelectorAll(".thumbnail");

    thumbnails.forEach(function(thumbnail) {
      const videoOverlay = thumbnail.querySelector(".video-overlay");
      const videoId = thumbnail.dataset.videoId;

      thumbnail.addEventListener("mouseenter", function() {
        const player = new YT.Player(videoOverlay, {
          videoId: videoId,
          width: "100%",
          height: "100%",
          playerVars: {
            autoplay: 1,
            controls: 0,
            rel: 0,
            showinfo: 0
          }
        });

        videoOverlay.style.display = "block";
      });

      thumbnail.addEventListener("mouseleave", function() {
        videoOverlay.innerHTML = "";
        videoOverlay.style.display = "none";
      });
    });
  }
</script>

I want the YT video to stop playing when I stop hovering on the thumbnail

Why isn’t my POST method updating my API in ReactJS?

I’m attempting to use an form to update a list from a dummy API but the POST method is not working. I’m not trying to use dependencies / axios for this. When I add a new item the list refreshes but doesn’t update. I also have a DELETE method that works fine.

  const [poke, setPoke] = useState([]);
  const [newPoke, setNewPoke] = useState("");

  useEffect(() => {
    fetch("/pokemon")
      .then((response) => response.json())
      .then((json) => setPoke(json));
  }, []);

const addPoke = () => {
    const name = newPoke.trim();
      fetch("/pokemon", {
        method: "POST",
        body: JSON.stringify({
          name,
        }),
        headers: {
          "Content-type": "application/json; charset=UTF-8",
        },
      })
        .then((response) => response.json())
        .then((data) => {
          setPoke([...poke, data]);
          setNewPoke("");
        });
  };

      <form>
        <input value={newPoke} onChange={(e) => setNewPoke(e.target.value)} placeholder="Add new Pokemon" />
        <button onClick={addPoke}>Add</button>
      </form>


        <ul>
          {poke.map((poke) => 
            <li key={poke.id}>{poke.name} <button onClick={() => deletePoke(poke.id)}>Delete</button></li> 
          )}
          
        </ul>

I tried following the same outline as my functional DELETE method but I feel like I’m missing a step. I also tried different URLs and that didn’t work. I’m expecting the li to update when I add a new item but it just refreshes without the new data.

how do I fix ‘process exited with code 1’ error in javascript

I am learning JavaScript and this error keeps poping out, here is my code: enter image description here

what I want this code to do is change the data in the array to user input and if there isnt any user input it just keeps it.

I tried using a different debugeer I tried changing up the code a bit, yet my code wouldent run.

Note: I know there is probablly a simple solution to this that I dident see but I am beginner and beginners do beginner things, and I want to fix it now so that I know how to fix this if it occurs in the future.

I’d like to know about the webpack and many chunk files

everyone!
How is it going?
I’m a shopify plus developer.
but I’m facing any problem.
I’d like to know about the webpack.
a few days ago, I started the new project and there is chunk files of the number more than 12,000 in assets directory.
Please let me know if you know about it.
I look forward to your kind reply.
Thanks
This is a screenshot in assets directory

I’d like to know the chuck files and webpack.