Flickering/being removed when using sortablejs with dcraw

I try to list files selected using multiple file input using the code below (also available at jsbin). When trying to move li items to sort and nest them, they start flickering and sometimes are dropped from the list and completely removed from DOM. Can it be solved while keep using dcraw and SortableJS? It seems to work

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Bootstrap-Flask Demo Application</title>

    <style>
        .handle {
            cursor: -webkit-grabbing;
            cursor: move;
        }
    </style>
</head>

<body>
    <input class="form-control" id="files" multiple="" name="files" required="" type="file">
    <div id="files-selected" class="mb-3">
        <ul class="list-group very-first-parent nested-sortable h-200">

        </ul>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/dcraw"></script>
    <script src="https://sortablejs.github.io/Sortable/Sortable.js"></script>
    <script>
        var filesField;
        var filesSelected;
        document.addEventListener('DOMContentLoaded', function () {
            filesField = document.getElementById("files");
            filesSelected = document.getElementById("files-selected");

            filesField.addEventListener('change', function (e) {
                var files = e.target.files;

                var reader = [];
                var filenames = Array.from(files).map(file => file.name);

                filesSelected.querySelector('.very-first-parent').innerHTML = '';
                filenames.forEach((filename, index) => {
                    // alert('file selected');
                    var file = files[index];
                    var li = document.createElement('li');
                    li.className = 'list-group-item';
                    li.innerHTML = `
                    <div class="d-flex align-items-center">
                        <i class="handle bi-arrows-move"></i>
                        <button type="button" class="btn btn-danger me-3 ms-3" onclick="dismiss(this)">
                            <span aria-hidden="true">&times;</span>
                        </button>
                        <span class="file-name">${filename}</span>
                        <!--spinner--><div class="spinner spinner-border ms-auto" role="status"><span class="visually-hidden">Loading...</span></div><!--/spinner-->
                    </div>
                    <ul class="list-group nested-sortable"></ul>
                    `;
                    showPreview(file, li);
                    filesSelected.querySelector('.very-first-parent').appendChild(li);
                });

                makeNestedSortable();
            });
        });
        function isImage(file) {
            const imageTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/bmp', 'image/webp'];
            return imageTypes.includes(file.type);
        }

        function isRawImage(file) {
            const rawImageExtensions = ['.nef', '.cr2', '.tiff'];
            return rawImageExtensions.some(ext => file.name.toLowerCase().endsWith(ext));
        }

        function isVideo(file) {
            const videoTypes = ['video/mp4', 'video/quicktime'];
            return videoTypes.includes(file.type);
        }

        function replaceSpinner(string_old, string_new) {
            return string_old.replace(/<!--spinner-->.*<!--/spinner-->/gi, string_new)
        }

        function showPreview(file, li) {
            if (isImage(file)) {
                const reader = new FileReader();
                reader.onload = function (e) {
                    li.innerHTML = replaceSpinner(li.innerHTML, `<img class="preview ms-auto" src="${e.target.result}" height="70" style="max-height: 70px;">`);
                };
                reader.readAsDataURL(file);
            } else if (isRawImage(file)) {
                // You can use a library like raw.js to decode raw images and show a preview
                const reader = new FileReader();
                reader.onload = (function (o) {
                    return function (e) {
                        // Get the image file as a buffer
                        var buf = new Uint8Array(e.currentTarget.result);

                        // Get the RAW metadata
                        var metadata = dcraw(buf, { verbose: true, identify: true }).split('n').filter(String);

                        // Extract the thumbnail
                        var thumbnail = dcraw(buf, { extractThumbnail: true });

                        // Create thumbnail
                        var blob = new Blob([thumbnail], { type: "image/jpeg" });
                        var urlCreator = window.URL || window.webkitURL;
                        var imageUrl = urlCreator.createObjectURL(blob);
                        li.innerHTML = replaceSpinner(li.innerHTML, `<img class="preview ms-auto" src="${imageUrl}" height="70" style="max-height: 70px;">`);
                    };
                })(file);
                reader.readAsArrayBuffer(file);
            } else if (isVideo(file)) {
                li.innerHTML = replaceSpinner(li.innerHTML, `<video src="${URL.createObjectURL(file)}" class="ms-auto" controls height="70" style="max-height: 70px;"></video>`);
            } else {
                li.innerHTML = replaceSpinner(li.innerHTML, `<span class="preview ms-auto">Preview not available</span>`);
            }
        }

        function dismiss(target) {
            var li = target.closest('li');
            var fileToDelete = li.querySelector('span.file-name').textContent;

            var dt = new DataTransfer();
            Array.from(filesField.files).forEach((file, i) => {
                if (file.name !== fileToDelete)
                    dt.items.add(file)

                filesField.files = dt.files // this will trigger a change event
            });

            li.remove();
        }

        function makeNestedSortable() {
            nestedSortables = [].slice.call(document.querySelectorAll('.nested-sortable'));
            console.log(nestedSortables.length);

            for (var i = 0; i < nestedSortables.length; i++) {
                new Sortable(nestedSortables[i], {
                    group: 'nested',
                    animation: 150,
                    fallbackOnBody: true,
                    // invertSwap: true,
                    swapThreshold: 0.5
                });
            }

        }
    </script>
</body>

</html>

How can I display an interactive JavaScript object on the page? [duplicate]

I consume a rest service that returns a fairly large javascript object. I want to display this object on the screen not in the console. I would like the displayed object to be interactive (have arrows to expand and collapse sub-objects) just like I can in the console.

console view

Is there any way for display chrome’s console output directly on the page? If not, can I use some library to display the javascript object the same way chrome’s console does? I don’t want to just print everything because the object is large and unreadable if you do that.

How To Solve CSP Blocking Problem in Javascript

btnLogin.Attributes.Add(“onclick”, ” javascript:return ABC(‘” & Convert.ToString(Session(“No”)) & “‘);”) This line is Call My ABC Function But When i Add CSP in My Code its NOt Working Can Someone Please Help Me

I try addEventListener And Also more thing

How to render an OWL component using t-component in Odoo view templates?

I am trying to render an OWL component in Odoo using t-component within my view template. However, the component is not loading, and nothing appears on the page.

Here’s what I’ve done:

1.My OWL Component:

/** @odoo-module **/

import { Component } from "@odoo/owl";

export class ProductImageGallery extends Component {
    setup() {
        console.log("ProductImageGallery component is working");
    }
}
ProductImageGallery.template = "multi_image_master.ProductImageGalleryTemplate";

2.My Component Template:

<template id="ProductImageGalleryTemplate" name="Product Image Gallery">
    <div>
        <h3>Product Image Gallery</h3>
        <p>Gallery of images for this product will appear here.</p>
    </div>
</template>

views/xml file

This is supposed to render the component using t-component:

<template id="ProductPageTemplate" name="Product Page">
    <t t-call="website.layout">
        <div id="product-page-content" class="container">
            <t t-component="multi_image_master.ProductImageGallery"/>
            <p>Hello Bharathi</p>
        </div>
    </t>
</template>

Controller:
The page is loaded via this controller.

from odoo import http
from odoo.http import request

class ControllerProductPage(http.Controller):
    @http.route('/shop', type='http', auth='public', website=True, csrf=False)
    def renderProductPage(self, **kwargs):
        return request.render('multi_image_master.ProductPageTemplate', {})

manifest file

   {
    "name": "Product Multi-Image Manager",
    "version": "0.1",
    "category": "Product",
    "depends": ["website"],
    "data": [
        "views/product_template.xml"
    ],
    "assets": {
        "web.assets_backend": [
            "multi_image_master/static/src/js/product_image_gallery.js",
            "multi_image_master/static/src/xml/product_image_gallery.xml"
        ]
    },
    "installable": True,
    "application": True,
    "license": "LGPL-3"
}

Issue:
When I load the /shop route, the page renders the static content but does not render the component (t-component=”multi_image_master.ProductImageGallery”). Also, the console.log() in the setup method of the component does not execute, indicating that the component is not being loaded.

Question:
How can I correctly render an OWL component using t-component in an Odoo view template? Am I missing something in the setup or registration? Any guidance would be appreciated.

cookies _clsk & _clck are not set as SameSite=None;Secure. Clarity implementation using GTM

I have implemented microsoft clarity using Google Tag Manager and currently I am not able to set the cookies as SameSite=None;Secure. I do not have any option in the clarity and google tag manager consoles.

How can I implement the cookies with SameSite=None and Secure?

I could set the cookies dynamically in my js but this might affect the clarity’s analysis and tracking. I’d prefer if I could set it in console or by some other way that doesn’t involve manually manipulating the cookie.

How to modify the code for the display of the lenticular effect under the Canvas feature in the Html

I am Derby. I am new in this community. I would need the help to modify the code for the display of the lenticular effect under the Canvas feature in the Html as the result of the demonstration on the website Lenti (https://danielgamage.github.io/lenti/). The source code is from the old project entitled “Lenti” (https://github.com/danielgamage/lenti?tab=readme-ov-file). I tried to combine the index.js into the html under one simple file to display lenticular effect in the html Canvas, but I cannot perform the same result as the demonstration on the website Lenti (https://danielgamage.github.io/lenti/). Attached is the source code. I wish the source code and files of the link from one old project would help you solve the problem and provide the solutions based on your specialty. Thank you.

<!DOCTYPE html>
<html>
<head>
<script>
/* global window */
class Lenti {
  constructor (options) {
    // Config
    this.container = options.container
    this.accelerometerEvents = (options.accelerometerEvents !== undefined)
      ? options.accelerometerEvents
      : true
    this.mouseEvents = (options.mouseEvents !== undefined)
      ? options.mouseEvents
      : true
    this.stripWidth = options.stripWidth || 16
    this.height = options.height || 50
    this.width = options.width || 50
    this.tiltMax = options.tiltMax || 45
    this.tiltMin = options.tiltMin || -45

    this.init = this.init.bind(this)
    this.sampleImages = this.sampleImages.bind(this)
    this.getImage = this.getImage.bind(this)
    this.handleSizing = this.handleSizing.bind(this)
    this.getBoxPosition = this.getBoxPosition.bind(this)
    this.checkVisibility = this.checkVisibility.bind(this)
    this.bindEvents = this.bindEvents.bind(this)
    this.destroy = this.destroy.bind(this)
    this.redraw = this.redraw.bind(this)
    this.handleMouse = this.handleMouse.bind(this)
    this.handleOrientation = this.handleOrientation.bind(this)
    this.remap = this.remap.bind(this)
  }

  // Initialize
  init () {
    this.images = [...this.container.querySelectorAll(`img`)]
    this.imageCount = this.images.length
    this.imageDataArray = [...Array(this.imageCount).keys()] // empty array w/ same length as this.images
    this.container.innerHTML += `<canvas />`
    this.canvas = this.container.querySelector(`canvas`)
    this.ctx = this.canvas.getContext(`2d`)
    this.tempCanvas = document.createElement(`canvas`)
    this.tempCtx = this.tempCanvas.getContext(`2d`)

    this.handleSizing()
    this.bindEvents()
    this.getBoxPosition()
    this.checkVisibility()
  }

  // Sample image
  sampleImages () {
    this.images.map((imageEl, imageIndex) => {
      if (this.imageDataArray[0]) {
        this.getImage(imageEl, imageIndex)
      } else {
        imageEl.addEventListener(`load`, function () {
          this.getImage(imageEl, imageIndex)
        }.bind(this))
        return imageEl
      }
    })
  }
  getImage (image, imageIndex) {
    this.tempCtx.drawImage(image, 0, 0, image.naturalWidth, image.naturalHeight, 0, 0, this.canvasWidth, this.canvasHeight)
    const currImageData = this.tempCtx.getImageData(0, 0, this.canvasWidth, this.canvasHeight)
    this.imageDataArray[imageIndex] = new Uint32Array(currImageData.data.buffer)
  }

  // Handle window resize
  handleSizing () {
    // use offsetWidth bc clientWidth = 0 when resizing
    // multiply by device pixel ratio to convert css pixels → device pixels
    this.canvasWidth = Math.floor(this.canvas.offsetWidth * window.devicePixelRatio)
    this.canvasHeight = Math.floor(this.canvasWidth * (this.height / this.width))
    this.canvas.width = this.canvasWidth
    this.canvas.height = this.canvasHeight
    this.tempCanvas.width = this.canvasWidth
    this.tempCanvas.height = this.canvasHeight
    // Resample images
    // careful on the fire rate here.
    this.sampleImages()
    this.imageData = this.tempCtx.getImageData(0, 0, this.canvasWidth, this.canvasHeight)
    this.getBoxPosition()
  }

  getBoxPosition () {
    const boxyRect = this.canvas.getBoundingClientRect()
    this.box = {
      top: boxyRect.top + window.pageYOffset
    }
  }
  // Check if canvas is in view
  checkVisibility () {
    const vTop = window.pageYOffset
    const vHeight = window.innerHeight
    if (vTop + vHeight < this.box.top ||
      this.box.top + this.canvasHeight < vTop) {
      // viewport doesn't include canvas
      this.visible = false
    } else {
      // viewport includes canvas
      this.visible = true
    }
  }

  // Event Binding
  bindEvents () {
    if (this.mouseEvents) {
      this.canvas.addEventListener(`mousemove`, this.handleMouse)
    }
    if (this.accelerometerEvents) {
      window.addEventListener(`deviceorientation`, this.handleOrientation)
    }
    window.addEventListener(`scroll`, this.checkVisibility)
    window.addEventListener(`resize`, this.handleSizing)
  }

  // Event Unbinding
  destroy () {
    this.canvas.removeEventListener(`mousemove`, this.handleMouse)
    window.removeEventListener(`deviceorientation`, this.handleOrientation)
    window.removeEventListener(`scroll`, this.checkVisibility)
    window.removeEventListener(`resize`, this.handleSizing)
  }

  // Redraw canvas
  redraw (balance) {
    // make sure data is loaded before redrawing
    if (this.imageDataArray[0]) {
      let data = this.imageData.data
      let data32 = new Uint32Array(data.buffer)

      const dataArray = this.imageDataArray
      const canvasWidth = this.canvasWidth
      const canvasHeight = this.canvasHeight
      const stripWidth = this.stripWidth
      const imageCount = this.imageCount

      const addOn = (balance * (imageCount - 1))

      for (let x = 0; x < canvasWidth; x++) {
        const set = (x % stripWidth / stripWidth) + addOn
        const setClamped = Math.floor(set)

        for (let y = 0; y < canvasHeight; y++) {
          const pixel = x + (canvasWidth * y)
          data32[pixel] = dataArray[setClamped][pixel]
        }
      }

      this.ctx.putImageData(this.imageData, 0, 0, 0, 0, this.canvasWidth, this.canvasHeight)
    }
  }

  // Handle mouse events
  handleMouse (e) {
    const balance = this.remap(e.offsetX / this.canvasWidth, 0, 1, 1, 0)
    this.redraw(balance)
  }

  // Handle device accelerometer events
  handleOrientation (e) {
    if (this.visible) {
      const clamped = Math.min(Math.max(e.gamma, this.tiltMin), this.tiltMax)
      const balance = this.remap(clamped, this.tiltMin, this.tiltMax, 1, 0)
      this.redraw(balance)
    }
  }

  // Map values from one range to another
  remap (value, inLow, inHigh, outLow, outHigh) {
    return outLow + ((value - inLow) * (outHigh - outLow) / (inHigh - inLow))
  }
}

export default Lenti

</script>
</head>

<body>
global.window = global

document.body.innerHTML = `
  <div data-lenticular-list="true" data-strip-width="8" data-tilt-min="-35" data-tilt-max="35">
    <img src="./images/1.png" crossorigin="anonymous" alt="" width="1024" height="1024" />
    <img src="./images/2.png" crossorigin="anonymous" alt="" width="1024" height="1024" />
    <img src="./images/3.png" crossorigin="anonymous" alt="" width="1024" height="1024" />
    <img src="./images/4.png" crossorigin="anonymous" alt="" width="1024" height="1024" />
  </div>
`

const el = document.querySelector('[data-lenticular-list]')

const testInstance = new Lenti({
  container: el,
  tiltMax: el.getAttribute('data-tilt-max'),
  tiltMin: el.getAttribute('data-tilt-min')
})

describe("Lenti", () => {
  it('instantiates properly', () => {
    expect(testInstance).toBeInstanceOf(Lenti)
  })
  it('initializes without error', () => {

    testInstance.init()
  })
})
describe("remap", () => {
  it('maps values from one range to another', () => {
    expect(testInstance.remap(5,    0, 10,   0, 100)).toEqual(50)
    expect(testInstance.remap(9,    0, 100,  0, 2)).toEqual(0.18)
    expect(testInstance.remap(7.5,  5, 10,   0, 2)).toEqual(1)
  });
})

</body>
</html>

Chained https requests using promises seem to be out of order

I’m trying to figure out how Promises work with multiple HTTPS requests in Javascript, but I have a problem where the results seem out of order with the request sequence. I’m using an ASP.NET Controller API implementation for a simple calculator, and Javascript to access the API. I seem to have a synchronization issue, but I can’t for the life of me work out why.

The CalculatorController:

using Microsoft.AspNetCore.Mvc;

namespace Wolflight.Calculator.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class CalculatorController : Controller
    {
        private const string TotalName = "Total";


        private decimal RetrieveTotal()
        {
            return ToDecimal(HttpContext.Session.GetString(TotalName));
        }

        private void StoreTotal(decimal value)
        {
            HttpContext.Session.SetString(TotalName, FromDecimal(value));
        }

        private static string FromDecimal(decimal value)
        {
            return value.ToString();
        }

        private static decimal ToDecimal(string? value)
        {
            if (value != null)
            {
                return Decimal.Parse(value);
            }
            else
            {
                return 0M;
            }

        }

        [HttpGet()]
        [Route("/api/Calculator/Total")]
        public decimal? GetTotal()
        {
            return RetrieveTotal();
        }

        [HttpPut()]
        [Route("/api/Calculator/Add")]
        public void AddValue(decimal value)
        {
            StoreTotal(RetrieveTotal() + value);
        }

        [HttpPut()]
        [Route("/api/Calculator/Subtract")]
        public void SubtractValue(decimal value)
        {
            StoreTotal(RetrieveTotal() - value);
        }

        [HttpPut()]
        [Route("/api/Calculator/Multiply")]
        public void MultiplyValue(decimal value)
        {
            StoreTotal(RetrieveTotal() * value);
        }

        [HttpPut()]
        [Route("/api/Calculator/Divide")]
        public void DivideValue(decimal value)
        {
            StoreTotal(RetrieveTotal() / value);
        }


    }
}

The site.js:

const uriBase = "/api/Calculator/";
const uriTotal = uriBase + "Total";
const uriAdd = uriBase + "Add";

let GetTotalValuePromise = function () {
    return new Promise(function (myResolve, myReject) {
        let total = fetch(uriTotal)
            .then(response => response.text())
            .catch(error => myReject('Unable to get total.', error));

        myResolve(total);
    })
};

let PutAddValuePromise = function (addValue) {
    return new Promise(function (myResolve, myReject) {
        fetch(uriAdd + '?value=' + addValue, { method: 'PUT' })
            .catch(error => myReject('Unable to add value.', error));

        myResolve();
    }
    )
};

function DisplayTotal(total) {
    const tBody = document.getElementById('totalDisplay');
    tBody.innerHTML = total;
}

function GetTotal() {
    UpdateDisplay();
}

function AddValue() {
    let value = document.getElementById('addValue').value;

    PutAddValuePromise(value)
        .then(function () {
            UpdateDisplay();
        });
}

function UpdateDisplay() {
    GetTotalValuePromise()
        .then(
            function (total) { DisplayTotal(total); },
            function (message, error) { console.error(message, error); }
        )
}

When I call AddValue() from a form button, the result is that sometimes the /Total call returns the value before the /Add occurs, and sometimes it returns the result after.

e.g.

  • Total = 0
  • Call AddValue, with element addValue as 5.

Network Requests:

  • /Add?value=5 (no response)
  • /Total – Response: 0.

OR

Network Requests:

  • /Add?value=5 (no response)
  • /Total – Response: 5.

Am I missing something in how Promises work, or is the problem on the server side?

If I call GetTotal manually after the AddValue, it always returns the correct value.

Return any possible palindrome [closed]

You are given a string S made of lowercase letters (‘a’-‘z’ and question marks (‘?’). You must replace each question mark in S with any lowercase letter. You are also given an integer K. After replacing the question marks, you may replace at most K characters in S with any lowercase letter.

Write a function that, given a string S of length N and an integer K, returns any palindrome that can be obtained by performing the operations described above. If it is not possible to obtain a palindrome from S, the function should return the string “NO”.

A palindrome is a string that reads the same both forwards and backwards. Some examples of palindromes are: “kayak”, “abba”,”zaz”.

Examples:

  1. Given S= “?ab??a” and K = 0, the function should return “aabbaa”.
  2. Given S = “guz?za” and K = 1, the function should return “NO”.
  3. Given S=”?gad?bcc?dg?” and K=2, the function may return “agadccccdaga”. It may also return “fgddcbbcddgf”, among other possible answers. The function is supposed to return only one of the possible answers.

Assume that:
N is an integer within the range [1 ..1,000];
K is an integer within the range [0 .. N];
String S is made only of lowercase English letters (‘a’-‘z’) and/or ‘?’ characteers.

In your solution, focus on correctness. The performance of your solution will not be the focus of the assessment.

Sorry I have not made any attempt.

Not able to remove nested array element in array using Javascript

In the below the screen shot , mentioned nested element as child array.

enter image description here

I wanted to remove child array element , I used below the script but it’s only remove first element.

removeChildWidget(parIndex:number,index:number){
    if (parIndex >= 0) {
       const widgetNumber = this.dashRightWidget[parIndex]?.widgetNumber;
       const widgeDashtNumber = this.dashboardWidgets[parIndex]?.widgetNumber;

       this.widgets.forEach((widget) => {
        if (widget.widgetNumber == widgeDashtNumber) {

          console.log("wid",widget.child[index])
          if (index >= 0) widget.child.splice(index, 1)
         console.log("wid",widget)
        }
      });
      console.log('final output', this.dashboardWidgets)
  
    }    
  }

Why is there a companiesArray.filter is not a function error? [duplicate]

I import a list of companies and internships in the backend as shown:

{
    "companies": [
        {
            "companyID": 1,
            ...
            
        }
    ],
    "internships": [
        {
            "internshipID": 1,
            ...
        }
    ]
}

Btw this is saved as companies:
const [companies, setCompanies] = useState([])
my useEffect:

useEffect(() => {
        const fetchCompanies = async () => {
            try {
                const data = await companyService.getAll();
                console.log('Fetched Companies:', data);
                setCompanies(data);
                setLoading(false);
            } catch (error) {
                console.error('Error fetching data:', error);
                setError('Error fetching data');
                setLoading(false);
            }
        };
        fetchCompanies();
    }, []);

I then use this code to filter through the arrays when someone searches for a specific one (just for companies):

const companiesArray = companies["companies"]

const filteredCompanies = companiesArray.filter(company =>
    company[searchBy]?.toLowerCase().includes(searchTerm.toLowerCase())
);
console.log('Filtered Companies:', filteredCompanies)

I then get the error that companies.filter isnt a function and im not sure why

Since companies is an array, so i thought this should work. What should i try?

Why is there a companies.filter is not a function error?

I import a list of companies and internships in the backend as shown:

{
    "companies": [
        {
            "companyID": 1,
            ...
            
        }
    ],
    "internships": [
        {
            "internshipID": 1,
            ...
        }
    ]
}

Btw this is saved as companies:
const [companies, setCompanies] = useState([])

I then use this code to filter through the arrays when someone searches for a specific one (just for companies):

const companiesArray = companies["companies"]

const filteredCompanies = companiesArray.filter(company =>
    company[searchBy]?.toLowerCase().includes(searchTerm.toLowerCase())
);
console.log('Filtered Companies:', filteredCompanies)

I then get the error that companies.filter isnt a function and im not sure why

Since companies is an array, so i thought this should work. What should i try?

how to add widgets that stack vertically with a sidebar and main content area?

Design a responsive dashboard with the following sections a header sidebar main content area and three widgets that stack horizontally.

answers with code hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh hhhhh hhh hhhh hhhhh hhhhhh hhh hhhhhh hhhhh hhhh hhhh h h hh hh hh hh hh hh h h h h hhhh hhhhhhhhhh

How to output server-side console.log to browser’s console in Express.js with EJS template?

I’m building a weather forecast application using Express.js and EJS templates (for my college’s class). Currently, my console.log statements in server.js are only visible in the terminal/server console. I want to make these logs visible in the browser’s developer tools console for debugging purposes.

Here’s my current codes:

server.js:

import express from 'express';
import bodyParser from 'body-parser';
import path from 'path';
import axios from 'axios';

const app = express();
const API_KEY = 'MY_API_KEY_FOR_OPENWEATHERMAP';
const PORT = 3000;

// Add these middleware configurations before your routes
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

// define the __dirname
const __dirname = path.resolve();

async function getForecast(city) {
    const url = `https://api.openweathermap.org/data/2.5/forecast?q=${city}&appid=${API_KEY}&units=metric`;
    // fetch version
    // const response = await fetch(url);
    // const data = await response.json();

    // axios version
    const response = await axios.get(url);
    const data = response.data;
    
    if (data.cod !== '200') {
        throw new Error(data.message);
    }
    
    return data;
}

app.get('/', (req, res) => {
    res.render(__dirname + '/weather.ejs');
});

app.post('/', async (req, res) => {
    try {
        const { city } = req.body;
        
        if (!city) {
            return res.status(400).render(__dirname + '/weather.ejs', { 
                error: 'City name is required' 
            });
        }

        const forecast = await getForecast(city);
        const dailyForecasts = forecast.list.filter((f, i) => i % 8 === 0);

        res.render(__dirname + '/weather.ejs', {
            city: forecast.city.name,
            forecasts: dailyForecasts
        });
    } catch (error) {
        res.render(__dirname + '/weather.ejs', { 
            error: error.message 
        });
    }
});

app.listen(PORT, () => {
    console.log(`Port ${PORT} is running.`);
});

weather.ejs

<!DOCTYPE html>
<html>
<head>
    <title>5-Day Weather Forecast</title>
    <style>
        .container { 
            max-width: 800px; 
            margin: 0 auto; 
            padding: 20px; 
        }
        .forecast-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 20px;
            margin-top: 20px;
        }
        .forecast-card {
            border: 1px solid #ddd;
            padding: 15px;
            border-radius: 8px;
            background: #f5f5f5;
        }
        .error {
            color: red;
            margin: 10px 0;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Weather Forecast</h1>
        
        <form action="/" method="POST">
            <input type="text" name="city" placeholder="Enter city name">
            <button type="submit">Get Forecast</button>
        </form>

        <% if (locals.error) { %>
            <div class="error"><%= error %></div>
        <% } %>

        <% if (locals.forecasts) { %>
            <% console.log(locals.forecasts) %>
            <h2>5-Day Forecast for <%= city %></h2>
            <div class="forecast-grid">
                <% forecasts.forEach(forecast => { %>
                    <div class="forecast-card">
                        <h3><%= new Date(forecast.dt * 1000).toLocaleDateString() %></h3>
                        <p>Temperature: <%= forecast.main.temp %>°C</p>
                        <p>Weather: <%= forecast.weather[0].main %></p>
                        <p>Humidity: <%= forecast.main.humidity %>%</p>
                        <p>Wind Speed: <%= forecast.wind.speed %> m/s</p>
                    </div>
                <% }) %>
            </div>
        <% } %>
    </div>
</body>
</html>

(My Local environment)

  • Mac M2
  • VSCode Version: 1.94.2 (Universal)
  • Chrome Version: 131.0.6778.70(Official Build) (arm64)

In my `weather.ejs` file, I used `<% console.log(locals.forecasts) %>` hoping to see the output in the browser’s console. However, it only shows up in my VSCode terminal instead.

How can I get the output to appear in the browser’s console?

Decimals in x axis only showing 0s and not rounding properly in ApexCharts, also “stepSize” not working

I’m attempting to create a line graph that should show an x and y axis that are both numbers to the second decimal. Say I pass a min of 0.0345 and a max of 5.2345, I would expect the first number on the x axis to be 0.035 and the last number on the x axis to be 5.23, however it shows me 0.00 and 6.00, why is this happening?

here is the xaxis portion of my chart options:

        xaxis: {
          type: 'category',
          categories: [],
          min: this.min,
          max: this.max,
          stepSize: 0.5,
          title: {
            text: 'Label'
          },
          labels: {
            formatter: function (val) {
              return val.toFixed(2);
            }
          },
        }

Another thing that’s happening is that the stepSize option doesn’t do anything! I am trying to do steps by .5 but it still steps up by whole integers. Any idea why?

Can share whatever code is relevant, let me know

React blank page on build

I’ve been learning React (kind of new to it) and I’m working on a project and I did an npm create vite@latest. So far everything works fine when I do run dev. However when I do run build, then go to the dist folder and open the index.html file I get a blank page.

So I do an inspect page in FireFox and I get these errors –

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resources at file:///assets/index-J7cny882.js. (Reason: CORS request not http)

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resources at file:///assets/index-BAXwXR6k.css. (Reason: CORS request not http)

I’m bit puzzled by this. Don’t know whats wrong or how to fix it. I did come across some things online that mentioned adding “homepage”: “.” to package.json. I did that but didn’t help.

I appreciate the help.

Thanks.