Why is the property “dadType” being set to all the options avalable and staying with the last one, rather than the one selected?

It’s basicaly a text based adventure game i thought would be a fun first project.

Game.js

const textElement = document.getElementById('text')
const optionButtonsElement = document.getElementById('option-buttons')

let factions =["Grill Dad","Sports Dad","Car Dad","Vacation Dad","Drama Dad","The Craft Dad"]
let state = {
  dadType : '',
  items : ''
}
//variables
function startGame() {
  state = {}
  showTextNode(1)
}
//make a function to show the first prompt and reset "state"
function showTextNode(textNodeIndex) {
  const textNode = textNodes.find(textNode => textNode.id === textNodeIndex)
  textElement.innerText = textNode.text
  while (optionButtonsElement.firstChild) {
    optionButtonsElement.removeChild(optionButtonsElement.firstChild)
  }
//function to remove options with no text
  textNode.options.forEach(option => {
    if (showOption(option)) {
      const button = document.createElement('button')
      button.innerText = option.text
      button.classList.add('btn')
      button.addEventListener('click', () => selectOption(option))
      optionButtonsElement.appendChild(button)
    }
  })
}
//function to add options till you run out
function showOption(option) {
  return option.requiredState == null || option.requiredState(state)
}
//function to check for "state"
function selectOption(option) {
  const nextTextNodeId = option.nextText
  if (nextTextNodeId <= 0) {
    return startGame()
  }
  state = Object.assign(state, option.setState)
  showTextNode(nextTextNodeId)
}
//function to advance to the next prompt and assign "state"
/*function randNum() {
let rand = Math.floor(Math.random() * 5)
}
//random generator
function getDadType(state){
  return state.dadType
}
//get dad type (not working)
*/
const textNodes = [
  {
    id: 1,
    text: 'Insert adventure description here pick a faction of dad to play as.',
    options: [
      {
        text: factions[0],
        setState: state = {dadType: 'grill dad'} ,
        nextText: 2
      },
      {
        text: factions[1],
        setState: state = {dadType: 'sports dad'},
        nextText: 2
      },
      {
        text: factions[2],
        setState: state = {dadType: 'car dad'},
        nextText: 2
      },
      {
        text: factions[3],
        setState: state = {dadType: 'vacation dad'},
        nextText: 2
      },
      {
        text: factions[4],
        setState: state = {dadType: 'drama dad'},
        nextText: 2
      },
      {
        text: factions[5],
        setState: state = {dadType: 'craft dad'},
        nextText: 2
      },
      {
        text: 'Placeholder for Random',
        setState: {},
        nextText: 2
      },
      {
        text: 'Placeholder for Back',
        nextText: 2
      }
     ]
  },
  {
    id: 2,
    text: "First part of backstory "+state.dadType,
    options:[
    {
      text: 'some things you could say',
      nextText: 1
    }
startGame()

The property “dadType” is supposed to be set to whatever dadtype you selected in the first text node, but rather than setting it, and then ignoring the rest of the option buttons, it seems to run through all the options. I want it to just set the last ones property. It will still go to the correct next window, but the correct property is not set.

I want to directly call the result value by arithmetic operation on two state values

I want to display (salePrice + manualSettlementAmount), (salePrice -manualSettlementAmount), values ​​according to the operation of sale state ‘+’, ‘-‘. And these result values ​​are put in settlementAmount.

And the arithmetic operation values ​​are calculated in onBlurSettlementAmount.

  const [form, setForm] = useState({
    sign: "+",
    salePrice: "",
    manualSettlementAmount: "",
    settlementAmount: 0,
  })

  const onChangeSign = (event: React.ChangeEvent<HTMLSelectElement>) => {
    setForm({...form, sign: event.target.value}); 
  } 

  const onChangeSalePrice = (event: React.ChangeEvent<HTMLInputElement> | any) => {
  setForm({...form, salePrice: event.target.value});
  }

  const onChangeManualSettlementAmount = (event: React.ChangeEvent<HTMLInputElement> | any) => {
    setForm({...form, manualSettlementAmount: event.target.value });

  }

  const onBlurSettlementAmount = (event: React.ChangeEvent<HTMLInputElement> | any) => {

    if (form.sign == '+') {
      setForm({ ...form, settlementAmount: (Number(form.salePrice) + Number(form.manualSettlementAmount ))})
    } 
  
    if (form.sign == '-') {
      setForm({ ...form, settlementAmount: (Number(form.salePrice) - Number(form.manualSettlementAmount ))})
    }
    
  }

return (
 <>
       <select value={form.sign} onChange={onChangeSign}>
                  <option label="+" value={"+"}>+</option>
                  <option label="-" value={"-"}>-</option>
       </select>

      <input type="text" value={form.manualSettlementAmount} onChange={onChangeManualSettlementAmount} />
      
      <input type="text" value={form.salePrice} onChange={onChangeSalePrice} />      

      <input type="number" disabled={true} value={form.settlementAmount} onBlur={onBlurSettlementAmount} />
 </>
)

However, the value of settlementAmount in input continues to appear as an initial value of 0, and the arithmetic operation value is not displayed. I don’t know why.

After inputting both sign and salePrice, whenever I input the manualSettlementAmount value, I want the settlementAmount value to be displayed as well.. How should I handle it?

Is it not possible to do arithmetic operations in onBlur?

How i fit the entire text and image to fit in this card component

I have made a carousel in which there is a right and left slider. the text and image coming in the card component are not fit. actually there are surpassing the container i want to make them fit.

Text and photo in card component
in this component is it not coming in card instead only some item. i want them to assign in proper order and within the frame but not happening

INDEX

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="style.css" />

    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
      integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
      crossorigin="anonymous"
    />
  </head>

  <body>
    <div class="slide hi-slide">
      <div class="hi-prev"></div>
      <div class="hi-next"></div>

      <ul>
        <li>
          <div class="card" style="width: 18rem">
            <img src="1.jfif" alt="Img 1" height="90px" />
            <div class="card-body">
              <h5 class="card-title">Card title</h5>
              <p class="card-text">
                Some quick example text to build on the card title and make up
                the bulk of the card's content.
              </p>
              <a href="#" class="btn btn-primary">Go somewhere</a>
            </div>
          </div>
        </li>
        <li>
          <div class="card" style="width: 18rem">
            <img src="images (1).jfif" alt="Img 1" height="90px" />
            <div class="card-body">
              <h5 class="card-title">Card title</h5>
              <p class="card-text">
                Some quick example text to build on the card title and make up
                the bulk of the card's content.
              </p>
              <a href="#" class="btn btn-primary">Go somewhere</a>
            </div>
          </div>
        </li>
        <li>
          <div class="card" style="width: 18rem">
            <img src="images (1).png" alt="Img 1" height="90px" />
            <div class="card-body">
              <h5 class="card-title">Card title</h5>
              <p class="card-text">
                Some quick example text to build on the card title and make up
                the bulk of the card's content.
              </p>
              <a href="#" class="btn btn-primary">Go somewhere</a>
            </div>
          </div>
        </li>
        <li>
          <div class="card" style="width: 18rem">
            <img src="images.jfif" alt="Img 1" height="90px" />
            <div class="card-body">
              <h5 class="card-title">Card title</h5>
              <p class="card-text">
                Some quick example text to build on the card title and make up
                the bulk of the card's content.
              </p>
              <a href="#" class="btn btn-primary">Go somewhere</a>
            </div>
          </div>
        </li>
        <li>
          <div class="card" style="width: 18rem">
            <img src="images.png" alt="Img 1" height="90px" />
            <div class="card-body">
              <h5 class="card-title">Card title</h5>
              <p class="card-text">
                Some quick example text to build on the card title and make up
                the bulk of the card's content.
              </p>
              <a href="#" class="btn btn-primary">Go somewhere</a>
            </div>
          </div>
        </li>
        <li>
          <div class="card" style="width: 18rem">
            <img src="images.png" alt="Img 1" height="90px" />
            <div class="card-body">
              <h5 class="card-title">Card title</h5>
              <p class="card-text">
                Some quick example text to build on the card title and make up
                the bulk of the card's content.
              </p>
              <a href="#" class="btn btn-primary">Go somewhere</a>
            </div>
          </div>
        </li>
        <li>
          <div class="card" style="width: 18rem">
            <img src="images.png" alt="Img 1" height="90px" />
            <div class="card-body">
              <h5 class="card-title">Card title</h5>
              <p class="card-text">
                Some quick example text to build on the card title and make up
                the bulk of the card's content.
              </p>
              <a href="#" class="btn btn-primary">Go somewhere</a>
            </div>
          </div>
        </li>
        <li>
          <div class="card" style="width: 18rem">
            <img src="images.png" alt="Img 1" height="90px" />
            <div class="card-body">
              <h5 class="card-title">Card title</h5>
              <p class="card-text">
                Some quick example text to build on the card title and make up
                the bulk of the card's content.
              </p>
              <a href="#" class="btn btn-primary">Go somewhere</a>
            </div>
          </div>
        </li>
      </ul>
    </div>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
    <script type="text/javascript" src="script.js"></script>
    <script>
      $(".slide").hiSlide();
    </script>
  </body>
</html>

STYLE

body {
  font-family: "Roboto Condensed", sans-serif;
  overflow-x: hidden;
  background-color: rgba(0, 0, 0, 0.9);
}

body {
  background-image: url(ur.jpg);
}

h1 {
  margin: 150px auto 30px auto;
  text-align: center;
  color: red;
}

.hi-slide {
  position: relative;
  width: 754px;
  height: 292px;
  margin: 115px auto 0;
}

.hi-slide .hi-next,
.hi-slide .hi-prev {
  position: absolute;
  top: 50%;
  width: 40px;
  height: 40px;
  margin-top: -20px;
  border-radius: 50px;

  line-height: 40px;
  text-align: center;
  cursor: pointer;
  background-color: #fff;
  color: black;
  transition: all 0.6s;
  font-size: 20px;
  font-weight: bold;
}

.hi-slide .hi-next:hover,
.hi-slide .hi-prev:hover {
  opacity: 1;
  background-color: #fff;
}

.hi-slide .hi-prev {
  left: -60px;
}

.hi-slide .hi-prev::before {
  content: "<";
}

.hi-slide .hi-next {
  right: -60px;
}

.hi-slide .hi-next::before {
  content: ">";
}

.hi-slide > ul {
  list-style: none;
  position: relative;
  width: 754px;
  height: 292px;
  margin: 0;
  padding: 0;
}

.hi-slide > ul > li {
  overflow: hidden;
  position: absolute;
  z-index: 0;
  left: 377px;
  top: 146px;
  width: 0;
  height: 0;
  margin: 0;
  padding: 0;
  border: 3px solid #fff;
  background-color: #333;
  cursor: pointer;
}

/* .hi-slide > ul > li > img {
  width: 100%;
  height: 100%;
  background-position: center;
} */

SCRIPT

(function ($) {
  var slide = function (ele, options) {
    var $ele = $(ele);

    var setting = {
      speed: 1000,

      interval: 10000,
    };

    $.extend(true, setting, options);

    var states = [
      {
        $zIndex: 1,
        width: 120,
        height: 150,
        top: 69,
        left: 134,
        $opacity: 0.2,
      },
      { $zIndex: 2, width: 130, height: 170, top: 59, left: 0, $opacity: 0.4 },
      {
        $zIndex: 3,
        width: 170,
        height: 218,
        top: 35,
        left: 110,
        $opacity: 0.7,
      },
      { $zIndex: 4, width: 224, height: 288, top: 0, left: 263, $opacity: 1 },
      {
        $zIndex: 3,
        width: 170,
        height: 218,
        top: 35,
        left: 470,
        $opacity: 0.7,
      },
      {
        $zIndex: 2,
        width: 130,
        height: 170,
        top: 59,
        left: 620,
        $opacity: 0.4,
      },
      {
        $zIndex: 1,
        width: 120,
        height: 150,
        top: 69,
        left: 500,
        $opacity: 0.2,
      },
    ];

    var $lis = $ele.find("li");
    var timer = null;

    $ele.find(".hi-next").on("click", function () {
      next();
    });
    $ele.find(".hi-prev").on("click", function () {
      states.push(states.shift());
      move();
    });
    $ele
      .on("mouseenter", function () {
        clearInterval(timer);
        timer = null;
      })
      .on("mouseleave", function () {
        autoPlay();
      });

    move();
    autoPlay();

    function move() {
      $lis.each(function (index, element) {
        var state = states[index];
        $(element)
          .css("zIndex", state.$zIndex)
          .finish()
          .animate(state, setting.speed)
          .find("img")
          .css("opacity", state.$opacity);
      });
    }

    function next() {
      states.unshift(states.pop());
      move();
    }

    function autoPlay() {
      timer = setInterval(next, setting.interval);
    }
  };

  $.fn.hiSlide = function (options) {
    $(this).each(function (index, ele) {
      slide(ele, options);
    });

    return this;
  };
})(jQuery);

Fibonacci sequence with recursive function works but I cant understand how

for anyone familiar with the Fibonacci sequence I wrote this function using a recursive algorithm that was on a bit of a whim. It is indeed working but I can not wrap my head around how. If anyone can explain this to me or point me to a resource I would be super appreciative

function fibonacciRecursive(n) {

    let startPoint = 0;
    let secondPoint = 1;
    let indexVal = 0;


    if (n === 0) {
        return startPoint;
    }

    if (n === 1) {
        return secondPoint;

    }

    indexVal = startPoint + secondPoint;

    startPoint = secondPoint;
    secondPoint = indexVal;

    return indexVal * fibonacciRecursive(n)

}

// fibonacci seq => 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144

My code works but I don’t think it is good. How to improve it?

Is there a way to beautify my code? It works but there repeated blocks and I am not sure that I’m using some functions in the right way.
I’m not new to javascript but I want to improve it and get rid of Bad Coding Habits.

Below is my code snippet that I’m using on the server to upload product images to cloud storage using multer and sharp.

const EasyYandexS3 = require('easy-yandex-s3')
const multer = require('multer')
const sharp = require('sharp')
const slug = require('slug')

const s3 = new EasyYandexS3({
  auth: {
    accessKeyId: process.env.KEY_ID,
    secretAccessKey: process.env.SECRET_KEY,
  },
  Bucket: process.env.BACKET, // Название бакета
  debug: false, // Дебаг в консоли
})

const storage = multer.memoryStorage()
const fileFilter = (req, file, cb) => {
  if (
    file.mimetype === 'image/jpeg' ||
    file.mimetype === 'image/jpg' ||
    file.mimetype === 'image/png'
  ) {
    cb(null, true)
  } else {
    cb(null, false)
  }
}

const upload = multer({
  storage,
  fileFilter,
  limits: {
    fileSize: 1024 * 1024 * 5, // ограничение до 5 мб
  },
})

const uploadFields = upload.fields([
  { name: 'cover', maxCount: 1 },
  { name: 'media', maxCount: 4 },
])

const uploadImages = (req, res, next) => {
  uploadFields(req, res, (err) => {
    if (err instanceof multer.MulterError) {
      if (err.code === 'LIMIT_UNEXPECTED_FILE') {
        return res.send('Превышено количество файлов.')
      }
    } else if (err) {
      return res.send(err)
    }
    next()
  })
}
const resizeImages = async (req, res, next) => {
  // Функция загрузки фотографий в бакет
  async function transform(size, file, filename, type) {
    const folder = slug(req.body.title)
    const resizedImgFilename = `${filename}-${size}`
    const resizedImgBuffer = await sharp(file.buffer)
      .resize(size)
      .toFormat('jpeg')
      .jpeg({ quality: 90 })
      .toBuffer()
    const upload = await s3.Upload(
      {
        buffer: resizedImgBuffer,
        name: resizedImgFilename,
      },
      `/products/${folder}/`
    )
    if (size === 800) {
      type.push(upload.Location.slice(0, -4))
    }
  }

  // Проверяем какие файл загружены
  if (req.files.media === undefined && req.files.cover === undefined) {
    return next()
  } else if (req.files.media === undefined) {
    await Promise.all(
      req.files.cover.map(async (file) => {
        const filename = Date.now() + Math.round(Math.random() * 1e2) + 'c'
        const type = req.body.cover
        await transform(800, file, filename, type)
        await transform(400, file, filename, type)
        await transform(250, file, filename, type)
      })
    )
  } else if (req.files.cover === undefined) {
    await Promise.all(
      req.files.media.map(async (file) => {
        const filename = Date.now() + Math.round(Math.random() * 1e2) + 'm'
        const type = req.body.media
        await transform(800, file, filename, type)
        await transform(400, file, filename, type)
        await transform(250, file, filename, type)
      })
    )
  } else {
    await Promise.all(
      req.files.media.map(async (file) => {
        const filename = Date.now() + Math.round(Math.random() * 1e2) + 'm'
        const type = req.body.media
        await transform(800, file, filename, type)
        await transform(400, file, filename, type)
        await transform(250, file, filename, type)
      })
    )
    await Promise.all(
      req.files.cover.map(async (file) => {
        const filename = Date.now() + Math.round(Math.random() * 1e2) + 'c'
        const type = req.body.cover
        await transform(800, file, filename, type)
        await transform(400, file, filename, type)
        await transform(250, file, filename, type)
      })
    )
  }
  next()
}

module.exports = {
  uploadImages,
  resizeImages,
}

Do all error objects in Javascript have the same structure?

I’m implementing error outputting modal in React web app and therefore instead of just using .catch((e) => console.log(e) I’m planning to pass the error details into a separate component and display 3 parts of this error object: name, message, stack, in separate fields of this component.

I know that standard Error type object has all of those properties, however, I was wondering whether there are some exceptions and some error could be returned without all of these fields?

How to store JSON in variable from fetch API

I can’t disclose the URL and what API I’m using because it breaches my work’s policy but hopefully I can provide enough information for assistance. I have a javascript function that runs on a on-click (I’m eventually building up a form that will make use of this fetch).

function getdata() {
let customer_po = document.getElementById("customer").value;
let access_token;
let data = {
    'grant_type': 'REDACTED'
}
let state = {
    "state": "REDACTED"
}
fetch(prod_auth, {
    method: "POST",
    headers: login_header,
    body: new URLSearchParams(data),
})
    .then(response => response.json())
    .then(result => console.log(result))

}

This works and I can access the JSON dictionary in the console. However, when I try to use my access_token variable declared earlier in such a way:

.then(response => response.json())
.then(result => {access_token = result["access_token"];})

and console.log(access_token) gives undefined. I need to access this variable in my getdata() function so it can be used as a parameter in another fetch call. Any help would be appreciated. Thank you!

Creating like button for multiple items

I am new to React and trying to learn more by creating projects. I made an API call to display some images to the page and I would like to create a like button/icon for each image that changes to red when clicked. However, when I click one button all of the icons change to red. I believe this may be related to the way I have set up my state, but can’t seem to figure out how to target each item individually. Any insight would be much appreciated.

`
 //store api data
 const [eventsData, setEventsData] = useState([]);

 //state for like button
 const [isLiked, setIsLiked] = useState(false);

useEffect(() => {
 axios({
  url: "https://app.ticketmaster.com/discovery/v2/events",
  params: {
    city: userInput,
    countryCode: "ca",
  },
  })
  .then((response) => {
    setEventsData(response.data._embedded.events);
  })
  .catch((error) => {
    console.log(error)
  });
});

//here i've tried to filter and target each item and when i 
console.log(event) it does render the clicked item, however all the icons 
change to red at the same time
  const handleLikeEvent = (id) => {
   eventsData.filter((event) => {
     if (event.id === id) {
       setIsLiked(!isLiked);
     }
    });
  };

return (
   {eventsData.map((event) => {
        return (
          <div key={event.id}>
              <img src={event.images[0].url} alt={event.name}></img>
              <FontAwesomeIcon
                 icon={faHeart}
                 className={isLiked ? "redIcon" : "regularIcon"}
                 onClick={() => handleLikeEvent(event.id)}
               />
          </div>
)

  `

 

Is it possible to tell if an async function is currently running at the top of the stack?

I’m trying to do something that involves a global context that knows about what function is running at the moment.

This is easy with single-threaded synchronous functions, they start off running and finish running when they return.

But async functions can pop to the bottom of the stack and climb back up multiple times before completing.

let currentlyRunningStack: string[] = [];
function run(id: string, cb: () => any) {
  currentlyRunningStack.push(id);
  cb()
  currentlyRunningStack.shift();
}

// works with synchronous stuff
run("foo", () => {
  run("bar", () => console.log("bar should be running"));
  console.log("now foo is running");
});

// can it work with asynchronous
run("qux", async () => {
  // async functions never run immediately...
  await somePromise();
  // and they start and stop a lot
});

Is it possible to keep track of whether or not an asynchronous function is currently running or currently waiting on something?

Jquery cannot find newly added elements [duplicate]

The Context

To make the explanation of my issue easier, I have created a small example:

Let’s say we have this simple website (index.html):

<!DOCTYPE html>
<html lang="en">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <body>
        <script id="navigation" src="nav.js"></script>
        <p>Amazing website content</p>
        <script src="something.js"></script>
    </body>
</html>

Let’s say the nav.js script imports our navigation bar from a nav.html into our index.html, so the script would look something like this:

fetch('nav.html')
    .then(res => res.text())
    .then(text => {
        let oldE = document.querySelector("script#navigation");
        let newE = document.createElement("div");
        newE.innerHTML = text;
        oldE.parentNode.replaceChild(newE,oldE);
    })

and for simplicity sake our “navigation bar” (nav.html) looks like this:

<ul class="class-nav">
  <li><a href="#">Home</a></li>
  <li><a href="#">News</a></li>
  <li><a href="#">Contact</a></li>
  <li><a href="#">About</a></li>
</ul>

Finally, we have something.js which is a javascript that uses jQuery to do some stuff, for now, we just want to be able to print out elements with the class name class-nav:

jQuery(document).ready(function($) {
    "use strict";
    var magic = function() {
        $('.class-nav').each(function() {
            console.log(this);
        });
    };
    magic();
});

The Issue

If I hardcoded my navigation bar (nav.html) to the webpage (index.html), the magic() function in something.js (that uses jQuery) works and is able to print out the navigation bar class-nav.

However, if we have it in the current setup, where we have our navigation bar added to the webpage from a separate nav.html file, the magic() function isn’t able to find class-nav.

Why? And how can I modify something.js to be able to retrieve class-nav using jQuery?

How to make these fixed cols’ width on a Bootstrap 4.0 table-responsive?

I’ve been trying to get this one to work based on similar questions/answers, but no success.

This is my attempt to fix the col width by explicitly setting each column’s width, but nothing changes!

<thead style="white-space: nowrap">
                <tr>
                  <th style="width: 1%" class="text-center">ClientID</th>
                  <th style="width: 2%" class="text-center">Task Nº</th>
                  <th style="width: 25%" class="text-center">Task</th>
                  <th style="width: 4%" class="text-center">Date Assigned</th>
                  <th style="width: 4%" class="text-center">Link To File</th>
                  <th style="width: 22%" class="text-center">Notes</th>
                  <th style="width: 14%" class="text-center">Approval</th>
                  <th style="width: 26%" class="text-center">Comments</th>
                </tr>
              </thead>

Here’s the Fiddle if you feel like giving a hand. Thank you!

Here’s

How to change the font in Algolia’s autocomplete?

I’m using Algolia’s autocomplete feature, which is working fine, but how can I change the font of the text shown in the autocomplete results? I’m using Javascript / JQuery

I would like to use a custom font (Cera) that I use in the rest of my website (which I’m loading via @font-face)

$('.algolia').autocomplete(
            var1,
            var2,
            var3,
            var4,
        )

TypeError: Cannot read properties of undefined (reading ‘create’). Happens when running npm run build:ssr

Getting an error when running npm run build:ssr to try to deploy my angular application
See the code below that the error is pointing to.
I’ve been trying to figure out why is giving me that error for weeks now.

const webpack = require('webpack');
const WebpackConfigFactory = require('@nestjs/ng-universal')
  .WebpackConfigFactory;

module.exports = WebpackConfigFactory.create(webpack, {
  // Nest server for SSR
  server: './server/main.ts'
});

Sort array in alphabetic order without using Array.sort in Java

I want to sort values of an array in alphabetic order, using merge sort. I have this code so far, but I when I run it, the output is jumbled and not in correct order. (Charlottetown, Fredericton, Montreal, Toronto, Vancouver, …)

If anyone has any advice/solutions, I would appreciate your help 🙂

Here is my current code.

    class Main {
  public static void main(String[] args) {
    String [] words = {"Montreal", "Halifax", "Toronto", "Vancouver",
              "Whitehorse", "Winnipeg", "Calgary", "Edmonton", 
              "Hamilton", "Regina", "Saskatoon", "Sault Ste. Marie", "Moncton", "Gander", "Fredericton", "Charlottetown"};
   for(int i = 0; i < words.length; i++)
{
    int smallest = i;
    for(int j = i + 1; j < words.length; j++) 
    {
        if(words[j].compareTo(words[i]) < 0)
            smallest = j;
    }
    
    String aux = words[i];
    words[i] = words[smallest];
    words[smallest] = aux;
}
for(int i = 0; i < words.length; i++)
{
    System.out.println(words[i]);
}
  }
}