Accessibility: using alt tag on image vs aria label on parent button

A functional image would generally be used as a button or link and hence in the markup it would be an img tag wrapped by a button tag or the anchor tag.

Since this image is functional, and assuming there is no accompanying text, we would need to provide a text alternative to the assistive technology. We can do this in many ways, but I am trying to understand if there is any difference (or rather, is either of these methods better than the other) in the following ways:

  • adding an alt attribute on the image explaining the functionality
  • adding an empty alt on image, but adding an aria-label on the parent button or link to explain the functionality

I have seen a lot of tutorials and examples which talk about adding an alt tag on the image, but couldn’t find any which compares these two methods. As per my testing, both work mostly similar with screenreaders.

References:
https://www.w3.org/WAI/tutorials/images/functional/

index.js not loading from main.js

I am working on a .net core MVC application. where I have integrated Twilio Video functionality.
In Views/Video/index.cshtml, reference for require js added like this,

<script data-main="../TwilioVideo/main" src="~/TwilioVideo/require.js"></script>

folder structure is like,

  • wwwroot
    • TwilioVideo
      • index.js

      • main.js

      • require.js

and the main.js file contains code,

    require.config({
paths: {
    "twilio-video": "https://media.twiliocdn.com/sdk/js/video/releases/2.4.0/twilio-video.min"
}
});
require(["index"], function () {

});

when I run the code index file not loading, in the source I can only see main.js and require.js. someone, please help me to understand what might be the issue?

Thanks in advance!

React infinite loop – onClick inside a render calls setState()

Pretty new to React. I’m having some problems rendering a button component. What I’m trying to do is to create a button that, when clicked, fetches some data and displays it under the button itself as a list. To do so, I’m trying to do a conditional rendering.
I used the state of the button component as the number of data fetched, initialized to zero. So the first time I would only render the button and not try to render the list at all. When the button gets clicked, the onClick event executes the fetch, getting the data. At this point, the state should be updated, but if I call setState() to update it, of course React advises me with a warning that I’m creating a infinite loop (I’m calling setState() inside a render() function after all).

The most common lifecycle components are not helping me, since when the component gets mounted the user has not yet pressed the button (can’t use componentDidMount() then) , and if I remove the setState() from the onClick function the component does not update, so I’m out of methods to call setState() from. And given that a component changing its props by itself is anti-pattern, I’m out of ideas.

Here is the code:

import { MapList } from './MapList';

export class ButtonFetcher extends React.Component
{

    constructor(props)
    {
        super(props);

        this.state = { numberOfMaps: 0 };

        this.mapArray = [];

        this.fetchHaloMaps = this.fetchHaloMaps.bind(this);
    }

    async fetchHaloMaps()
    {
        const url = 'https://cryptum.halodotapi.com/games/hmcc/metadata/maps'   

        fetch(url, {
            "method": 'GET',
            "headers": {
                        'Content-Type': 'application/json',
                        'Cryptum-API-Version': '2.3-alpha',
                        'Authorization': 'Cryptum-Token XXX'
                     }
        })
        .then(response =>      
            response.json())   
        .then(res => {  
                    
            let d;
            let i=0;
            for (; i< res.data.length; i++)
            {
                d = res.data[i];
                this.mapArray[i] = d.name;
            }

            this.setState(({  
                numberOfMaps : i
            }));  
        })  
        .catch(error => {   
            console.log("There was an error: " + error);
        });
    }


    render()
    {
        if (this.state.numberOfMaps === 0)
        {
            return (
                <button type="button" onClick={this.fetchHaloMaps} >Retrieve giafra's last maps!</button>
            )
        }

        else
        {
            return (
                <div>
                    <button type="button" onClick={this.fetchHaloMaps} >Retrieve giafra's last maps!</button>
                    <MapList mapNames={this.mapArray} />
                </div> 
            )
        }
        
    }

}

Mobx get latest value of a property

I have the following code inside a mobx store:

  order: string = "";
  
  processOrder = async (order: string) => {
    ...
    console.log(order, "--", this.order);
   ...
  };

and the console.log is allways outputing -- ,and it looks like this is the output is the same even if I change the start value ,but i have no idea how can i get the actual value of that property.

How to remove ‘GET?’ string from URL when submitting a GET form

I’m working on a search feature. When user enters a keyword, he or she should get a list of brands.

The current URL is ‘http://127.0.0.1:8000/brand/list’

And if I search for “bag”, it should be “http://127.0.0.1:8000/brand/list?keyword=bag”

But now, it’s “http://127.0.0.1:8000/brand/list/GET?keyword=bag”. I wanna remove the ‘GET?’ thing. How can I do this? I don’t know why but I can’t find any solutions to this.

<section id="brand-list">
  <form action="GET">
    <input type="text" name="keyword">
    <button>Search</button>
  </form>
 </section>

Thank you!

Mocha finds global variable is undefined when extended by class

I have the following ES6 module from a Chromecast receiver that I would like to test using Mocha…

// SUT - app.js
import { Queue } from 'queue.js'
export const app = async () => {
  const context = cast.framework.CastReceiverContext.getInstance();
  const options = {};
  options.queue = new Queue();
  context.start(options);
}

This code runs inside a Chromecast user agent which provides access to the global cast object. This cast object exposes an api which in turn enables the JS thread to interact directly with the Chromecast CAF SDK. This cast variable is always available at run time.

The Queue class is slightly unusual because in order for it to work according to the CAF framework documentation, is must extend an abstract class from the framework cast.framework.QueueBase

// queue.js
class Queue extends cast.framework.QueueBase {
  initialize(){
    // build queue here
  }
}

Now I would like to write some unit tests to check my app function is correct. For example:

// app.test.js
import { app } from 'app.js';
it('should do some stuff', async function () {
  // inject a mock cast object
  global.cast = {
    framework: {
      QueueBase: class {},
      CastReceiverContext: {
        getInstance: () => {},
      },
    },
  };
  await app();
  // Make some assertions
});

However, even though I am injecting a mock using global.cast, which is sufficient for all regular references to the cast object, in the case where a class is extending the injected cast object, apparently it is not yet available and I receive the following error:

ReferenceError: cast is not defined

I found an ugly hack to make this error disappear. If I place the following snippet above the class declaration then I can inject the mock at runtime and it not only works for Mocha but also for execution on the Chromecast device….

try {
  // The following line throws in Mocha's node environment
  // but executes fine on the Chromecast device
  if (cast) {
  }
} catch {
  global.cast = {
    framework: {
      QueueBase: class {},
    },
  };
}

export class Queue extends cast.framework.QueueBase {
...

However, I would like to find a better solution so that I don’t have to pollute my production code with this hack which is only there to allow me to run tests.

My .mocharc.yml file looks like this:

require:
  - '@babel/register'
  - 'ignore-styles'
  - 'jsdom-global/register'
  - 'babel-polyfill'

… and my command to run tests is:

mocha –recursive –use_strict

finally, my .babelrc file looks like this:

{
    "presets": [
        [
            "@babel/preset-env"
        ]
    ],
    "plugins": [
        "inline-svg",
        "import-graphql"
    ]
}

How to iterate through object through multiple level nested objects

There is a object with some file informations for each library. Some of these have values for dependencies, which can be a npm package or another library in this object.

Now I need to get the npm packages of all affected libraries.

I tried to create this reduce, but with that I only get the first level npm packages.

export const getUsedDeps = (deps) => {
    const directDependencies = deps.reduce(
    (depsAcc, dep) => {
        if (dep?.type === 'static') {
        const isNpmPackage = dep.target.match(regexIsNpm)
        const depName = isNpmPackage?.[1]
        const version = getVersion(depName)

        // Check if npm package, then add to result object, else iterate dependencies
        if (depName && version) {
            depsAcc[depName] = version
        } else if (!isNpmPackage) {
            return {
            ...depsAcc,
            ...getUsedDependencies(rootPackage, deps, depName)
            }
        }
        }
        return depsAcc
    },
    {}
    )
    return directDependencies
}

@apollo/client (which is in a library dependency) is missing – see example data below.

In this example you could easily get all npm packages of languages-backend by using map(). But there is also languages-util-graphql as a dependency. So in this case I also have to get "npm:@apollo/client".
In this way of course there could be multiple level nested dependecies. So I have to handle the looping. That’s why I tried to use reduce().

Another problem is how to also handle circuit dependencies – which should be there, but I have to handle this error. For example languages-util-graphql depends on languages-backend.

const deps = {
"languages-backend": {
    "data": {
    "files": [
        {
        "file": "apps/languages/backend/project.json",
        "hash": "55ca6cd2c772625ed7f6265c587366244ec33c1c"
        },
        {
        "file": "apps/languages/backend/src/app/app.module.ts",
        "hash": "4d583158d652329bee41c3424d6d98a72b6a5fd5",
        "deps": [
            "npm:@nestjs/common",
            "npm:@nestjs/graphql",
            "npm:@nestjs/config"
        ]
        },
        {
        "file": "apps/languages/backend/src/app/app.service.ts",
        "hash": "4bc9870b67f86c46ea8b4d9fbfcda1982cd73151",
        "deps": [
            "npm:@nestjs/common"
        ]
        },
        {
        "file": "apps/languages/backend/src/app/dictionary/dictionary.resolvers.ts",
        "hash": "798e56123950ad6fbb3c3229a3f1c3408415e397",
        "deps": [
            "npm:@nestjs/graphql",
            "languages-util-graphql"
        ]
        },
        {
        "file": "apps/languages/backend/src/app/dictionary/dictionary.service.ts",
        "hash": "c66a1106fad68ac4d9d4164fd129524314851f71",
        "deps": [
            "npm:check-types",
            "npm:nanoid",
            "npm:@nestjs/common",
            "npm:mongodb",
            "languages-util-graphql"
        ]
        },
        {
        "file": "apps/languages/backend/src/main.ts",
        "hash": "ee24ba3ce6ee4ed7ac398e5c59785ed2ec5b573e",
        "deps": [
            "npm:helmet",
            "npm:@nestjs/common",
            "npm:@nestjs/core"
        ]
        }
    ]
    }
},
"languages-util-graphql": {
    "data": {
    "files": [
        {
        "file": "libs/languages/util-graphql/src/lib/generated.ts",
        "hash": "882e919d29255013450a5a0644c6a0a6f8bf4b37",
        "deps": [
            "npm:@apollo/client"
        ]
        },
        {
        "file": "libs/languages/util-graphql/tsconfig.json",
        "hash": "667a3463d1d1367fdaa0a33be5eded304f7873f1"
        }
    ]
    }
}
}

The result should be (the version values get calculated in an external function):

{
    '@nestjs/common': '^8.2.3',
    '@nestjs/graphql': '^9.1.2',
    '@nestjs/config': '^1.1.6',
    'check-types': '^11.1.2',
    'nanoid': '^3.1.30',
    'mongodb': '^4.2.1',
    'helmet': '^4.6.0',
    '@apollo/client': '^3.5.6',
    '@nestjs/core': '^8.2.3'
}

moving LI elements from UL to another UL ..and toggle them

Just started programming and wanted to create a simple to-do list.
I wanted to add the feature that when somebody clicks on any LI element of an UL, it will move it to another UL with the title checked. Couldn’t find a valid solution though, I tried to store the UL’s into variables and target their children through addeventlistener, but without much success.
Any ideas would be much appreciated! Thanks

(as I’m a beginner, vanilla JavaScript would be preferable.)

Discrepancy in Javascript Intl.DateTimeFormat() Outputs for the Islamic (Hijri) Calendar between ‘islamic’ and ‘ar-SA’

The 3rd March 2022 is the end of this Hijri Month (month of Rajab for this year 1443 AH); i.e. 30 Rajab 1443 AH.

The month of Rajab for the year 1443 AH is 30 days in accordance with the Islamic (Hijri) Calendar in accordance with all websites, applications, MS Office, and Windows calendars.

When using the javascript Intl.DateTimeFormat() to display the Islamic (Hijri) date for the 3 March 2022 using the islamic calendar option, it will give the Islamic Hijri Date of (1 Shaʻban 1443 AH). This result is one day after the month of Rajab (i.e. the 1st of the following month) and it calculated the month Rajab to be 29 days rather than 30 days.

However, if the option passed to the Intl.DateTimeFormat() is ar-SA (i.e. arabic-Saudi Arabia), it will give the correct result. This is strange because the ar-SA locale uses the Islamic (Hijri) calendar by default.

Is this an error/bug or is it the correct internal workings of javascript?

Is there a more robust method to get the Islamic Date in Javascript other than using the ‘ar-SA’ locale (but not using external libraries)?

See the code example below:

I have tested this in node and chrome and it gives the same resulting discrepancy.

let date = new Date("2022-03-03");
let options = {year:'numeric', month:'long',day:'numeric'};

let format = new Intl.DateTimeFormat('ar-SA-u-nu-latn', options);
console.log("3 March 2022 with 'ar-SA'         :"+format.format(date)+ " ==> means: 30 Rajab 1443 AH");

format = new Intl.DateTimeFormat('en-u-ca-islamic-nu-latn', options);
console.log("3 March 2022 with Islamic Calendar: "+format.format(date));

Unable to get socket event in ReactJS from XMPP Strophe

I am new to React JS. I am trying to connect to XMPP Server and get the presence, message event from it. Earlier I used just plain JavaScript and I was able to do that easily, but in case of React JS.

I am able to login to XMPP server with the below code, but when presence changes, or there is new message I don’t get the function call back or the event executed.

What am I doing wrong here ?

import React, {Component} from 'react';
import logo from './logo.svg';
import  { Strophe, $pres, $iq } from 'strophe.js'

import './App.css';

var BOSH_SERVICE = 'wss://chat.example.com:7443/ws';
var connection = null;
connection = new Strophe.Connection(BOSH_SERVICE, { 'keepalive': true });

class App extends Component {
 
  constructor(){
    super();
    this.state ={
      string: ""
    }
    console.log("Strophe is "  ,  Strophe);
  }

  componentDidMount() {
    
    connection.connect("[email protected]","rajan", onConnect);
    connection.send($pres().tree());
    connection.addHandler(onMessage, null, 'message', null, null, null);
    connection.addHandler(onPresence, null, "presence");
    console.log("New Connection is " , connection);

  }
  
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <p>
            Edit <code>src/App.js</code> and save to reload.
          </p>
          <a
            className="App-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
          >
            Learn React
          </a>
        </header>
      </div>
    );
  }

  
}

function onConnect(status) {

  if (status == Strophe.Status.CONNECTING) {
      console.log('Synergy is connecting.');
  } else if (status == Strophe.Status.CONNFAIL) {
    console.log('Synergy failed to connect.');

  } else if (status == Strophe.Status.DISCONNECTING) {
    console.log('Synergy is disconnecting.');
  } else if (status == Strophe.Status.DISCONNECTED) {
    console.log('Synergy is disconnected.');

  } else if (status == Strophe.Status.CONNECTED) {
    console.log('Synergy is connected.');
      // set presence
      connection.send($pres().tree());
      connection.addHandler(onMessage, null, 'message', null, null, null);
      connection.addHandler(onPresence, null, "presence");
    
  }
} 

function onMessage(message){
  console.log("Message is" , message); 
}

function onPresence(presence){
  console.log("Message is" ,presence); 
}
export default App;

In traditional JavaScript code, the below code was working for me. Whenever I would receive a message or the presence changed for the user, I used to get the update.

Here is the JavaScript Code.

var BOSH_SERVICE = 'wss://chat.example.com:7443/ws';
var connection = null;
var con;

$(document).ready(function () {
    connection = new Strophe.Connection(BOSH_SERVICE);  
    connection.rawInput = rawInput;
    connection.rawOutput = rawOutput;
});    

function onConnect(status)
{
    if (status == Strophe.Status.CONNECTING) {
        console.log('Strophe is connecting.');
        
    } else if (status == Strophe.Status.CONNFAIL) {
        console.log('Strophe failed to connect.');
    } else if (status == Strophe.Status.DISCONNECTING) {
        console.log('Strophe is disconnecting.');
    } else if (status == Strophe.Status.DISCONNECTED) {
        console.log('Strophe is disconnected.');
    } else if (status == Strophe.Status.CONNECTED) {
       console.log('Strophe is connected.');
    }
}

function onPresence(presence) {
  
    console.log("Presence changed" , presence);  
    var presence_type = $(presence).attr('type'); // unavailable, subscribed, etc...
    var from = $(presence).attr('from'); // the jabber_id of the contact
  
    var actualjid= from.substr(0, from.indexOf('/')); 
  
    var escaped  = actualjid.replace(/@/g, "_");
    var bareJID  = escaped.replace(/./g,"_");  
  
    return true;
  }

function onRoster(stanza) {

    $(stanza).find("item").each(function() {
         console.log(" Status " + $(this).attr("jid") +" ::: "+ presense);
     });
}

click event doesn’t change font size [duplicate]

I have this code:

<!DOCTYPE html><html><head></head><body>

<button id="b12">12px</button>
<button id="b14">14px</button>
<button id="b16">16px</button>

<script>
document.getElementById('b12').onclick = clickHandler(12)
document.getElementById('b14').onclick = clickHandler(14)
document.getElementById('b16').onclick = clickHandler(16)
function clickHandler(size) {
    return function() {
        document.body.style.fontSize = `${size}px`
    }
}
</script>

</body></html>

But the buttons font size doesn’t seem to change when I click one.
I also made a codepen here:
https://codepen.io/trufo/pen/eYedaLE
If anyone could tell me what I’m missing in that code, that would be greatly appreciated.

Why is writing with JSONStream running out of memory?

I have an application that writes a large array of big-but-not-huge JSON objects to an output file. The objects are created, written, and then discarded (i.e. I don’t keep them all around). I am using JSONStream in an attempt to make memory usage a non-issue, but it isn’t working.

Here is a simple example that shows the issue I’m having:

let fs = require('fs');
let JSONStream = require('JSONStream');

const testfile = 'testfile.json';
const entcount = 70000;
const hacount = 10*1024;

console.log(`opening ${testfile}`);
let outputTransform = JSONStream.stringify();
let outputStream = fs.createWriteStream(testfile);
outputStream.on('finish', () => console.log('finished'));
outputTransform.pipe(outputStream);

console.log(`writing ${entcount} entries, data size ${hacount*2}`);
for (let n = 0; n < entcount; ++ n) {
    let thing = {
        index: n,
        data: 'ha'.repeat(hacount)
    }
    outputTransform.write(thing);
}

console.log('finishing');
outputTransform.end();

This example uses JSONStream to stream 70000 objects, each roughly 20kB, to a file (this is in the ballpark of my actual application). However, it runs out of memory around 45000 (full output at end of post):

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaS
cript heap out of memory
 1: 0092D8BA v8::internal::Heap::PageFlagsAreConsistent+3050

Also I’ve noticed that as I’m calling outputTransform.write, the file size stays at 0 (it’s also 0 after the above OOM). It doesn’t start growing until outputTransform.end is called. So I’m assuming the output data is being buffered somewhere and is eating up the heap.

The behavior I expected was that outputTransform.write would cause output to be written immediately, or at least buffered in a manageably sized buffer; and so I can write as many objects I want without worry about an OOM.

So my question is, is there some way to get JSONStream to not hold all this data in memory?

Increasing the heap size isn’t really an option, because it still presents a memory-bound upper limit.


Full output:

$ node index.js

opening testfile.json
writing 70000 entries, data size 20480

<--- Last few GCs --->

[22256:022DA970]     4589 ms: Mark-sweep 918.8 (924.6) -> 918.3 (921.9) MB, 30.6
 / 0.0 ms  (+ 69.8 ms in 33 steps since start of marking, biggest step 9.7 ms, w
alltime since start of marking 104 ms) (average mu = 0.116, current mu = 0.082)
finalize increm[22256:022DA970]     4593 ms: Scavenge 920.2 (921.9) -> 918.1 (92
6.1) MB, 2.3 / 0.0 ms  (average mu = 0.116, current mu = 0.082) allocation failu
re

<--- JS stacktrace --->

==== JS stack trace =========================================

    0: ExitFrame [pc: 00DDCB97]
Security context: 0x1c200469 <JSObject>
    1: /* anonymous */ [0D080429] [index.js:~1] 
[pc=203C4C90](this=0x0d0804c5 <Object map = 1ED0021D>,0x0d0804c5 
<Object map = 1ED0021D>,0x0d0804a5 <JSFunction require (sfi = 3025687D)>,
0x0d08045d <Module map = 1ED204A5>,0x3024f3c1 <String[#59]: index.js>,0x0d080449 
<...

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaS
cript heap out of memory
 1: 0092D8BA v8::internal::Heap::PageFlagsAreConsistent+3050

How can I re-fetch an API automaticaly until data is fetched succesfully?

I have an API that sometimes doesn’t work. I would like for the App to refetch automaticaly if this happens until it gets the necessary data. How can I do that? I’m thinking that maybe this could be done by using a dependency on the useEffect hook, but I’m not clear on how to do it.

Lets say we have this App component

export default function App() {
  const [data, setData] = useState([])

  useEffect(() => {
    getData({ setData })
  }, [])

   return [
    <h3>
      {data[0].title}
    </h3>
  ]
}

And this API component

const url = 'https://some-random-url.com/whatever-api'

export default function getData({ setData }) {

  axios.get(url)
    .then((response) => {
      let dataArray = response.data.results
      setData(dataArray)
    })
    .catch((error) => {
      console.log(error)
    })
}

In javascript table structure how can add dom element or image with text on the table cell

In javascript table structure I already created my table and put my data . However I also need put multiple colored circle but I couldn’t.

I already defined colored circles for legend part (which show colored circles meaning ) I can use them or I can use a image .it is not important. I just want to see this structure.

I just simulate with excel in order to make understand better

I directly try to put my circles but only show “object HTML” text . Please help me, My javascript background is not good.