Getting coordinates of selected area using Rails, Stimulus and OpenLayers

I want to draw a rectangle over a static image (OpenLayers jpg, not a map). My Main issue is with Stimulus.

How do I set up the drawing which is probably a click and drag, but could be a click-click.

Rails Stimulus HTML

  <% doc_image_width= @year.doc.image.metadata['width'] %>
  <% [email protected]['height'] %>
  <% docUrl = rails_blob_url(@year.doc.image) %> 

  <div id="snmap"
    data-controller="snippet-draw"
    data-snippet-draw-target="snmap"
    data-snippet-draw-url-value="<%= docUrl %>"
    data-snippet-draw-width-value="<%= doc_image_width %>"
    data-snippet-draw-height-value="<%= doc_image_height %>"
    data-action="click->snippet-draw#getSnippetCoordinates" 
    style="width: <%= doc_image_height %>px; height: <%= doc_image_height %>px">
  </div>

app/javascript/controllers/snippet_draw_controller.js.

I don’t know how to approach this. Shouldn’t be repeating things in two methods. When I click on the image, the image is selected instead of drawing. Maybe point me to some posts or blogs about the actions

import { Controller } from "@hotwired/stimulus"
import Map from 'ol/Map';
<import other ol (openlayers)>
export default class extends Controller {
  static targets = [ "snmap", "snippetCoords"]
  static values = {
    url: String,
    width: Number,
    height: Number,
  }

connect() {
  let source = new VectorSource();            
  const docURL = this.urlValue;
  const docWidth  = this.widthValue;
  const docHeight = this.heightValue;
  const extent = [0, 0, docWidth, docHeight];

  let projection = new Projection({ units: 'pixels',  extent: extent});

  let docSource = new Static({ url: docURL, projection: projection, imageExtent: extent });

  let docLayer = new ImageLayer({ source: docSource, extent: extent});

  let map = new Map({
    layers: [docLayer],
    target: snmap,
    view: staticView,
    extent: extent,
   });
  } 

  getSnippetCoordinates() {
    <repeat of everything in connect() up to map>
    let map = new Map({
      layers: [docLayer, drawLayer],
      target: snmap,
      view: staticView,
      extent: extent,
    });

    let drawLayer = new VectorLayer({
      source: source
    });
    draw.on('drawend', function(event) {
      let boxCoords = event.feature.getGeometry().getCoordinates();
      let boxCoordsStringified = JSON.stringify(boxCoords);
      let boxCoordsStringifiedParsed = JSON.parse(boxCoordsStringified);
      return this.snippetCoordsTarget.boxCoordsStringified
    });
  }

How to make side navbar

I wanna make a side navbar we’re it’s hidden at first but then you click on an icon then it all appears on the left of the screen with info and stuff on it then you can close it by clicking on a X in the navbar how I would code that

I tried multiple stuff but it didn’t work I want the navbar to come out from the left and have it’s own separate column of info separate from the page

difference between text selectors in JS for DOM

what’s the difference between .value, innerText, innerHTML, textContent, TEXT_NODE.
sometimes I pick them randomly and use them in if conditions and the results are either always true or always false no matter what the condition is so please someone explain when should I use each of those

Why I can’t deploy my Node Js app in Cpanel?

I’m trying to deploy my node js application in my cpanel, I already created a subdomain as well as setup the node js, but when I click npm install, it takes so much time, when I visit my path folder, and check my node_modules, nothing is updated, and once I refresh my cpanel, I get an error of

can't acquire lock for app: %(app)s

I tried deleting the package-lock.json, and then re-upload the files again.

This is what happened when I click the npm install again and when I visit my path, the modules are already uploaded but when I visit the website itself.

Error occurs

I get an error of this

Website

This is my index.js

import express from 'express';
import cors from 'cors'
import studentQuestion from './routes/students/part_1_question.js'
import employeeQuestion from './routes/employee/part_1_question.js'
import facultyQuestion from './routes/faculty/part_1_question.js'
const app = express()
app.use(cors());
app.use(express.json());

app.get('/', (req,res) =>{
    res.send("Hello World")
})

//ung /employees galing sa front end, pero magging dynamic depende sa category, student, faculity
app.use('/api/students', studentQuestion)
app.use('/api/employees', employeeQuestion)
app.use('/api/faculty', facultyQuestion)


app.listen(4000, () =>{
    console.log(`Website is running at port http://localhost:${4000}`)
})

Next JS ERR_HTTP_HEADERS_SENT error after GraphQL mutation fails

So I’m using Next JS API routes and in one of such routes I’m calling a GraphQL mutation using Apollo, something like:

// pages/api/foo.js

import { initializeApollo } from '~/server/apollo'

export default function handler(req, res) {
  const client = initializeApollo()
  try {
    await client.mutate({ mutation: FooDocument })
    // this works
    res.status(200).send({ foo: '...' })
  } catch {
    // this fails
    res.status(500).send({ error: '...' })
  }
}

as you can see if the mutation fails I get a server error when calling res.status(500).send({ error: '...' }):

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

But If the mutation succeeds I got no error when calling res.status(200).send({ foo: '...' }).

Does anyone knows why this happens? I guess that my best alternative is to call this mutation only in the frontend but I would like to know if there’s a way around this.

Trigger Delete on Keyboard

The code snippet provided will Pop Up Alert when Backspace and Delete Key is Pressed on Keyboard with the cursor clicked on the textbox. However, now I want to implement it in my codepen demo here, but I am unsure on how to do it. I want the alert box to pop up only when the cursor is placed on the grey box only if the Backspace and Delete Key is Pressed. I will really appreciate any help I can get.

Click on Text Box and Press on Delete and Backspace for Pop UP
<br>
<input id="input">

<script>
var myinput = document.getElementById('main-container');
input.onkeydown = function() {
  if (event.keyCode == 8) {
    alert('you pressed backspace');
    //event.preventDefault();
  }

  if (event.keyCode == 46) {
    alert('you pressed delete');
    //event.preventDefault();
  }
};

</script>

I have tried var myinput = document.getElementById('zoomPanCont'); , which is the div id but it does not work unfortunately.

Javascript for loop going past set range

I am using a p5.js function that I created to detect whether rook moves in my chess game are legal. I am using a for loop to go through the spaces on the board between the rook’s current position and its target destination and check if they are occupied by a value other than “space.” If any of the squares looped through are occupied by a piece, it will set a boolean variable to false. The function will then return the variable. The problem is that the function is always returning false because it is looping through all the spaces in front of the rook, rather than just the ones between it and the destination.

I have tried using console.log to see what the values of the spaces are, and they are returning all of the spaces’ values. How can I fix this issue?
Here is my code:

for (var y = startingY; y > targetY, y--;) {
      console.log(board[startingX][y].name)
      if (board[sx][y].name != "space") {
          open = false
          }
        }  

Why does this ternary show the expression if true when the variable “gameOver” is false?

I’ve just started using ternaries in React, so maybe I’ve got something backwards. I have the variable gameOver which is false by default. Then, I have this ternary:

{gameOver ? <p>Game over, man!</p> : <p>Keep playing!</p>}

This shows “Game over, Man!”, but I expected it to show “Keep playing!”, the expression if false, since gameOver is false.

If I change it to !gameOver in the ternary, then it shows “Keep playing!” Why?

Here is a codesandbox link.

Puppeteer not working after fresh install TypeError: selector.startsWith is not a function

I just started with Puppeteer. Basically I did the following in my puppeteer directory:
npm init -y, npm install puppeteer, touch index.js, inserted the boilerplate code into index.js, and node index.js.

The problematic piece of code is:

const n = await page.$("div[data-test-component='StencilReactRow']")

and the error I am getting is:

TypeError: selector.startsWith is not a function pointing at GetQueryHandler.js:51

I am shocked that there are so few results about this on the web regarding Puppeteer. Any help would be greatly appreciated!

My node version is v18.14.2

How can I detect support for SMS from JavaScript?

I am implementing a SMS share button using the sms://... link. The problem is, if a user doesn’t have an SMS app on their device, this link will do nothing, or cause an error. I’d like to be able to find any possible way of identifying whether the current browser is able to execute that link so I can hide the button if not.

Currently I’m just using a media query to hide the button on all desktop viewports. However this is a very imprecise net to cast since many tablets are in those screen sizes and often have SMS support, and so do many desktops.

Is there an API or wrangling of data available in the browser that can give me a better answer to the question than a media query can?

How to load alternative script file if first script file is not loaded using Javascript or jQuery?

I am working on a live site hosted on webflow. I have two javascript files

  1. http://localhost:3000/dev.js
  2. https://cdn.jsdelivr.net/live.js

I want to link them in a way if dev.js is not loaded, it will load live.js

I am using the following script, but it keeps pinging dev.js and showing errors in the console. Is there a better way to achieve this?

<script>
console.log('yes');
$.getScript( "http://localhost:3000/dev.js" )
  .done(function( script, textStatus ) {
    //do nothing
  })
  .fail(function( jqxhr, settings, exception ) {
    //load alternative script
    $.getScript( "https://cdn.jsdelivr.net/live.js" )
      .done(function( script, textStatus ) {
        //do nothing
      })
      .fail(function( jqxhr, settings, exception ) {
        console.log( 'Error online script loading' );
    });
});
</script> 

API JSON object returns Promise pending in console when logged from variable. Value is visible only inside the function [duplicate]

I am trying to get wanted data from API through the function and then let a = function to get value of data wanted.

let url = "https://itunes.apple.com/search?term=eminem&media=music&limit=2.";
function fetchData() {
    return fetch(url).then(function (response) {
        return response.json();
    })
        .then(function (json) {
            return json;
        });
}

fetchData().then(function (result) {
    console.log(result);
});

var a = fetchData().then(function (result) {
    console.log(result);
});
console.log(a);

console.log(result) inside the function shows correct data but I need it outside the function to work with it. As I am a beginner I got an idea to call the function inside variable then use that variable to work with data inside using for loop.

What am I missing?

Thank you!

Trying to get JSON value outside the function to work with data collected. I’ve read through a lot of answered questions on this problem but just got more confused so I am asking for precise instructions to see where I failed.

Dynamic Filter With Typescript in Angular

I need to use filter to typescript, however, I need to pass a dynamic column, so I can use these methods elsewhere.

That’s my job.

adcionarLista(selecionados: any, lista: any) {
    const dados = [];
    for (const selecao of selecionados) {
      dados.push(lista.value.filter((v: any) => v.idRelatorio === selecao));
    }
    return dados;
  }

due to the part (v.idRelatorio), the code is leaded to only one file.

And I would like to do it like this:

let’s say i want to do my condition through the name column;

adcionarLista(selecionados: any, list: any: field: any) {
    const dados = [];
    for (const select of selecionados) {
      dados.push(list.value.filter((v: any) => v.field === select));
    }
    return dados;
  }

In this example above I would check if the value of the column name is equal to the select.

But if at another time I pass the age value in the field, then the field would already assume that it would look for the age column.

React re-rendering of nested list functional components

Should not custom component CheckboxLabels retrieve different checked prop after each handleCheckboxChange call? Currently I can not get the clicked checkbox to checked state before closing the enveloping upper list. Only opening and closing the upper list updates the state of the nested checkbox components.

type CheckboxLabelsProps = {
  columns: string[]
  table: string
  checked: Map<string, boolean>
  handleCheckboxChange: (event: React.ChangeEvent<HTMLInputElement>) => void
}

function CheckboxLabels({ columns, table, checked, handleCheckboxChange }: CheckboxLabelsProps) {
  return (
    <FormGroup>
      {columns.map((column, index) => (
        <FormControlLabel
          key={column}
          label={column}
          value={`${table}-${column}`}
          control={<Checkbox checked={checked.has(`${table}-${column}`) ? checked.get(`${table}-${column}`) : false} onChange={handleCheckboxChange} />}
        />
        ))}
    </FormGroup>
  );
}


export default function NestedList({ items }: PropsType) {
  const [open, setOpen] = React.useState([] as boolean[]);
  const [checked, setChecked] = React.useState(new Map() as Map<string, boolean>);

  useEffect(() => {
    // sets open state as array of false
  }, [items])

  useEffect(() => {
    // sets checked state for each nested checkbox element as false
  }, [])

  const handleCheckboxChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const [table, column] = event.target.value.split('-');
    const newChecked = checked;
    const key = `${table}-${column}`;
    newChecked.set(key, !checked.get(`${table}-${column}`));
    setChecked(newChecked);
  };

  const handleClick = (index: number) => {
    const collapsedIndex: number = index;
    const newOpen = [...open];
    newOpen[collapsedIndex] = !(open[collapsedIndex]);
    setOpen(newOpen);
  };

  return (
    <List>
      {items.map((item, index) => 
        {
          const tables = Object.keys(item.payload.columns);
          const columnsForTable = new Map<string, string[]>();
          tables.forEach((table) => {
              const key = table;
              const value = item.payload.columns[table];
              columnsForTable.set(key, value);
          });
          const columnsFT = Object.entries(Object.fromEntries(columnsForTable.entries()));
          return  columnsFT.map(([table, columns]: [string, string[]], index ) => 
                      (
                        <Box key={table}>
                          <ListItemButton onClick={() => handleClick(index)}>
                            <ListItemIcon>
                            <InboxIcon />
                            </ListItemIcon>
                            <ListItemText primary={table} />
                            {open[index] ? <ExpandLess /> : <ExpandMore />}
                          </ListItemButton>
                            <Collapse in={open[index]} timeout="auto" unmountOnExit>
                                <List key={table} component="div" disablePadding>
                                  <ListItem sx={{ pl: 4 }}>
                                    <Box sx={{ display: 'flex', flexDirection: 'column', ml: 3 }}>
                                      <CheckboxLabels columns={columns} table={table} checked={checked} handleCheckboxChange={handleCheckboxChange}/>
                                    </Box>
                                  </ListItem>
                                </List>
                            </Collapse>
                          </Box>
                      ))
          })
      }
    </List>
  );
}