Wednesday, December 4, 2019

Destructuring and Spreading in JavaScript

I wanted to get a better understanding of destructuring and spreading for a project I am working on. So I created this jsfiddle to understand it better.

What I really wanted to know was would happen if I tried to unpack a value from an object that did not exist. And then what would subsequently happen if I tried to use that value in a spread operation. For example:
const testObj = {
    a: [1, 2, 3],
    b: [4, 5, 6]
}

const { a } = testObj;
const { b } = testObj;
const { c } = testObj;

const combined = [...a, ...b, ...c];

The short answer is this: if you try to destructure a non-existent property, then you get an undefined value. And if you try to use that undefined value in a spread operation, JavaScript will throw an error: TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))

Sunday, September 15, 2019

PHP: Failed opening required filepath in Unknown on line 0

I ran into this error message while working on a personal project. I had set up the code in my Microsoft OneDrive folder to sync it between my laptop and my desktop. I suspected the error might have something to do with OneDrive, so I copied my code to another folder on my computer. Sure enough, it worked perfectly. Finally, I discovered the problem. It was a setting in OneDrive called "Files On-Demand". What I suspect is that the files were simply just 0-byte stubs on my desktop. So when PHP requested them, it failed. Once I unchecked this box and OneDrive downloaded all of the necessary files, it worked just fine.

Monday, April 29, 2019

Make Your Console Statements Stand Out

Using the Chrome DevTools to debug your JavaScript code is great. Breakpoints are a great way to analyze what is going on with your code. But sometimes you just need an old-fashioned console.log. But if you have an app that is already chatty in development mode with a lot of console messages, there is a way to make your console statement stand out. You may not know that you can format your console statements with CSS. For example:
console.log('%cExample', 'background: #a00; color: #fff; font-weight: bold; font-size: 110%');
will look like this in your console:

Example

A better way to do it, though, is to use a JavaScript template literal. For example:
let xyz = 123;
console.log('%c%s', 'background: #a00; color: #fff; font-weight: bold; font-size: 110%', 
  `The value of xyz is ${xyz}`);
Will produce:

The value of xyz is 123

Now to make it even easier, we can create a VS Code snippet:
"color-console": {
 "prefix": "color-console",
 "body": [
  "console.log('%c%s', 'background: #a00; color: #fff; font-weight: bold; font-size: 110%', `$1`);"
 ],
 "description": "Color coded console message"
},
And then voilĂ 

Tuesday, April 23, 2019

Sequelize Newbie Mistake

Today I inherited a piece of code that looked something like this:
const records = Records.findOne({
    where: {
        pk: 'blah',
    },
    sort: ['dateField', 'DESC']
});
It did not seem to be sorting correctly, so I looked up ordering for Sequelize. Since I am new to Sequelize, I did not know that the correct property is order and not sort. But when I changed it, I got this error message:
Unknown column \'DESC\' in \'order clause\'
It took me longer than I care to admit to see what the issue was. If you pass an array of single items to the order property, it will use them all as part of the sort. So the backend SQL query looked something like this:
SELECT * FROM my_table WHERE pk = 'blah' ORDER BY dateField, DESC
What I really wanted was to pass it an array of arrays to sort on. So the correct code looks like this:
const records = Records.findOne({
    where: {
        pk: myValue,
    },
    order: [
        ['dateField', 'DESC']
    ],
});
Notice that order property now is an array containing an array specifying the field to sort on and the direction with which to sort it.

Thursday, March 21, 2019

Case-insensitive matching with case-sensitive replacements in JavaScript

That title is a mouth full. Here is what I was trying to accomplish: I had a search term that I wanted to highlight in a body of text. So my code needed to match all occurrences of the search term and then enclose the matched text within some HTML in order to format it. Seems simple enough, but I ran into a couple of issues.

Let's say I am going to format a phone number from a string of digits. I would do it like this:
let phone = '5551234567';
phone = phone.replace(/(\d{3})(\d{3})(\d{4})/, '$1-$2-$3');
But that syntax doesn't work for me here because I need to pass the search pattern as a variable name and I need to specify the "i" and "g" flags. So this code will not work:
const searchTerm = 'xyz';
myText = myText.replace(/searchTerm/ig, 'THE'); // Not valid
First, I use the RegExp constructor to define my pattern.
const searchTerm = 'xyz';
const pattern = RegExp(searchTerm, 'ig');
let myText = 'xyz XYZ xYz';
myText = myText.replace(pattern, 
  `<span class='highlight'>${searchTerm}</span>); 
  // Results will all be lowercase because searchTerm is lowercase
Then I had to create an array of matches that I could then loop through and replace each one individually:
let sampleText = 'This is my sample text: test Test TEST';
const searchText = 'test';
const pattern = new RegExp(searchText, 'ig');
const matches = sampleText.match(pattern, sampleText);
if (matches !== null) {
 matches.forEach((match) => {
  sampleText = sampleText.replace(match, `${match}`);
 });
}
To see this in action, take a look at this JSFiddle.

Thursday, January 31, 2019

Using Workspaces

I'm a big fan of Visual Studio Code's workspaces. In the past, I've used them to separate my work into different projects and applications or different parts of an application (like server-side vs client-side). At the moment we are wrapping up a release at my job so I am often jumping between various tickets. It occurred to me this morning that I could create a new workspace for each ticket. The reason this is helpful is because sometimes I may need these 4 files open for one ticket and a different 5 files open for a different ticket. So instead of keeping them all open and jumping around, I can have just the files I need open for that particular ticket to avoid confusion.

So then the thought occurred to me, what if I could do the same with Chrome? Fortunately, there is an extension for that. Now I can open my application and all my reference material in one workspace and a different set of tabs in another workspace.

Simple. Efficient. I like that.

Tuesday, January 8, 2019

Find This Not That in jQuery

Today at work, I came across a jQuery find statement that was selecting a bunch of different elements but I needed to excluded a single class from the selection. Of course, I hit Google and Stack Overflow for an answer but nothing was quite exactly what I needed. I found the solution and also learned something else about jQuery in the process. So here is what I came up with.

The solution was to chain a filter call to the find statement using the not selector.

Here is a contrived example on CodePen. In this example, I am selecting all buttons except for the btn-danger and btn-warning classes:
var myButtons = $('#main')
     .find('button')
     .filter(':not(".btn-danger,.btn-warning")');

Something I noticed in the console is that there is an object created called prevObject. This object contains the matched elements before the filter is applied which could be useful.

 
Blogger Templates