Why is let not the same as var in this case in JavaScript

I recently saw a post saying never use var in JavaScript (ECMAScript6). Always use const or let instead. I have the following code snippet from the YouTube API docs that uses var.

function changeBorderColor(playerStatus) {
    var color;
    if (playerStatus == -1) {
        color = "#37474F"; // unstarted = gray
    } else if (playerStatus == 0) {
        color = "#FFFF00"; // ended = yellow
    } else if (playerStatus == 1) {
        color = "#33691E"; // playing = green
    } else if (playerStatus == 2) {
        color = "#DD2C00"; // paused = red
    } else if (playerStatus == 3) {
        color = "#AA00FF"; // buffering = purple
    } else if (playerStatus == 5) {
        color = "#FF6DOO"; // video cued = orange
    }
    if (color) {
        document.getElementById('existing-iframe-example').style.borderColor = color;
    }
}

When I change var color to let color, my linter suggests that the line near the bottom (if (color)) will always evaluate to true. That is “condition is always true”. I’m having trouble understanding what let causes the behavior and var does not.

Solution:

The linter is just wrong.

The last if (color) is not affected at all by whether you use let color or var color. It’s only affected by whether any of the if tests for playerStatus hit their conditions.

As others have said, you can probably work around the linter bug by assigning a default value to color as in let color = null; and that will likely avoid the confusion the linter got itself in.

acess function in objected, nested inside another function

Im trying to manage a connection instance, using a function to handle idle connection disconnect issues, using mysql database and node.js

At moment, i’ve got following code (coffescript):

mysql = require 'mysql'

handleDisconnect = () ->
  connection = mysql.createConnection
    host: 'localhost'
    user: 'root'
    password: 'passroot'
    database: 'mydb'

  connection.connect (err) ->
    if err
      console.log 'Error connecting to db: ', err
    setTimeout handleDisconnect, 2000

  connection.on 'error', (err) ->
    console.log 'db error', err
    if err.code == 'PROTOCOL_CONNECTION_LOST'
      handleDisconnect()
    else
      throw err

  handleDisconnect.instance = connection

module.exports = handleDisconnect

and

express = require 'express'
router = express.Router()
connection = require('../database')().instance

bcrypt = require 'bcryptjs'

router.post '/', (req, res) ->
  credential = connection.escape req.body.credential
  password = connection.escape req.body.password
  res.send credential+password

module.exports = router

Problem is, when i try to access the route, i get following error:

Cannot read property ‘escape’ of undefined

What am i doing wrong?

Solution:

I believe your issue is that the final line of handleDisconnect is returning the instance, so you’re trying to get the instance from instance, not from handleDisconnect. So you’ll need the function to return itself at the end if you want to access properties on it.

You also want the function to be using the equivalent of “this” (@ in coffeescript) rather than specifically referring to handleDisconnect.

Example code:

mysql = require 'mysql'

handleDisconnect = () ->
  connection = mysql.createConnection
    host: 'localhost'
    user: 'root'
    password: 'passroot'
    database: 'mydb'

  connection.connect (err) ->
    if err
      console.log 'Error connecting to db: ', err
    setTimeout handleDisconnect, 2000

  connection.on 'error', (err) ->
    console.log 'db error', err
    if err.code == 'PROTOCOL_CONNECTION_LOST'
      handleDisconnect()
    else
      throw err

  @instance = connection
  @

module.exports = handleDisconnect

Although I’d personally just do the following, don’t bother with “instance” at all:

  1. Use @connection in your function
  2. Scrap the @instance = connection
  3. Get the function to return itself
  4. Access it with require('../database')().connection.

Add object to an object from a function in JavaScript

First I hit the button Add then ‘Show’ and lastly Show Object

The problem is that when I hit the button Show Object I get only one object for the last input element instead one object for each input element.

How can I add new objects from inside a function without loosing most of them?

Here is the code:

$(document).ready(function() {
  // body...
  var tableInput = "<tr><td><input type='text'/></td><td><input type='text'/></td></tr>";
  var obj = {};
  const rowNo = 2;

  $("h1").text("Helllo Sonq");
  console.log("function called!");

  $("#add").click(function() {
    $("#table").append(tableInput)
  })

  $("#show").click(function() {
    $(":text").each(function(index) {
      console.log(index + ': ' + $(this).val());
      var rowno = "row" + parseInt(index / rowNo)
      obj[rowno] = new Object()
      obj[rowno]["element" + index.toString()] = $(this).val();
      // obj[rowno]["element" + index.toString()] = $(this).val();
    })
  })

  $("#show-object").click(function() {
    console.log(obj);
  })
})
<!DOCTYPE html>
<html>

<head>
  <title>Page Title</title>
</head>

<body>
  https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js
  http://js/js.js
  <h1>Hello Riko!</h1>
  <button id="add">Add</button>
  <button id="show">Show</button>
  <button id="show-object">Show Object</button>
  <table id="table">
    <tr>
      <th>Name</th>
      <th>Age</th>
    </tr>
  </table>
</body>

</html>

Into the function :

$("#show").click(function(){
    $(":text").each(function(index) {

I want to add an object to the global obj for each iterated input type=text element.

Solution:

The first time you do var rowno = "row" + parseInt(index/rowNo) , var rowno is filled with row0. Since 0/2 is 0.

But then, the second time, the same row, var rowno = "row" + parseInt(index/rowNo) gives you also a value of 0, since 1/2 does 0.5, wich gets truncated to 0. By doing so, you are replacing the object at position ‘row0’, wich is what an object in javascript does.

You should not use parseInt

How to use ternary operator in return statement that returns an array

I use React 16.0.

I want to return an element conditionally as shown below.

import React from 'react';

export default class App extends React.PureComponent {
    render () {
        return [
            
, {condition ?
: null}, {condition ?
: null} ]; } }

Is there a way to do this without any extra methods or conditional statements outside the return statement?

thank you for reading.

Solution:

You’re inside an array, not JSX. There is no need to use the curly braces, just do your ternary operation and then put a comma after it.

return [
    
, condition ?
: null, condition ?
: null ];

Keep in mind, this will create indices with null as their value in the array if the conditions are false.

How to magically get Object key?

It is possible to get hero key in the translate function?

let books = {
  hero: translate([
    'Batman',
    'Superman',
    'Ironman'
  ])
}

function translate(param1) {
  return ...
}

Maybe there is some magic how to get calling key name ? 🙂 Thanks!

Solution:

You’re asking if a function called as part of a property initializer in an object initializer can access the name of the property its return value will be used to initialize.

No, it can’t. Functions have no knowledge of how their return value will be used.