Web Development Articles
Javascript Null Coalescing Operator ??
The double question mark ?? in javascript is referred to as the null coalescing operator. It was introduced in JavaScript ES2020. It allows you to check for null or undefined variable. In most cases the order of operation for this operator follows the math and comparison operators. Below are a few examples:
Example 1:let myval = null;console.log(myval ?? 20); // output is 20 because myval is null
Example 2:console.log(myval ?? 20); // output is 20 because myval is undefined
Example 3:let myval = [];console.log(myval ?? [1,2,3]); // output is [] because it isn't null and it's not undefined
If the myval is anything other than null or undefined, the output will be the value of the right-hand side of the equation.
Laravel Eloquent ORM Polymorphism Examples
Laravel Eloquent ORM Polymorphism
In Laravel's Eloquent ORM, polymorphism refers to polymorphic relationships, which allow a model to belong to more than one type of model using a single association.
This is useful when you have a relationship that can apply to multiple different models without having to create separate foreign keys or pivot tables for each type. Examples would be Users and Products that each have one or more images.
Let’s take a look at different types of polymorphic relationships commonly used in Laravel Eloquent ORM.
One-to-One (Polymorphic)
Example: An Image model could belong to either a User or a Product.
// Image model
public function imageable()
{
return $this->morphTo();
}
// User model
public function image()
{
return $this->morphOne(Image::class, 'imageable');
}
// Product model
public function image()
{
return $this->morphOne(Image::class, 'imageable');
}
Table Definitions: User, Product models can both have an Image. Notice Image.imageable_id and Image.imageable_type. This can join on both User.id and Product.id tables.
CREATE TABLE users (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
email VARCHAR(255) UNIQUE
);
CREATE TABLE products (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
price DECIMAL(10,2)
);
CREATE TABLE images (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
url VARCHAR(255),
imageable_id BIGINT UNSIGNED, -- FK ID (user.id or product.id)
imageable_type VARCHAR(255), -- Model class (App\Models\User/App\Models\Product)
INDEX idx_imageable (imageable_id, imageable_type)
);
One-to-Many (Polymorphic)
Example: A Comment model could belong to both a Post and a Video.
// Comment model
public function commentable()
{
return $this->morphTo();
}
// Post model
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
// Video model
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
Table Definitions: Post, Video models can both have a Comment. Notice Comment.commentable_id and Comment.commentable_type. This can join on both Post.id and Video.id tables.
CREATE TABLE posts (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
body TEXT
);
CREATE TABLE videos (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
url VARCHAR(255)
);
CREATE TABLE comments (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
body TEXT,
commentable_id BIGINT UNSIGNED, -- FK ID (post.id|video.id)
commentable_type VARCHAR(255), -- Model class (App\Models\Post|App\Models\Video)
INDEX idx_commentable (commentable_id, commentable_type)
);
Many-to-Many (Polymorphic)
Example: A Tag model can be applied to both Post and Video.
// Tag model
public function posts()
{
return $this->morphedByMany(Post::class, 'taggable');
}
public function videos()
{
return $this->morphedByMany(Video::class, 'taggable');
}
// Post model
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
}
// Video model
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
}
Table Definitions: Both Post, Video models can have multiple Tags. Also, a Tag can belong to multiple Post, Video models. Notice the pivot table taggables…
CREATE TABLE tags (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) UNIQUE
);
CREATE TABLE posts (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
body TEXT
);
CREATE TABLE videos (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
url VARCHAR(255)
);
CREATE TABLE taggables (
tag_id BIGINT UNSIGNED, -- FK to tags.id
taggable_id BIGINT UNSIGNED, -- FK ID (post.id or video.id)
taggable_type VARCHAR(255), -- Model class (App\Models\Post / App\Models\Video)
PRIMARY KEY (tag_id, taggable_id, taggable_type),
INDEX idx_taggable (taggable_id, taggable_type)
);
Using the Javascript Switch Statement
Overview of the Switch Statement
The switch statement is a control structure available in almost every programming and scripting language. It allows the developer to execute different blocks of code based on the value of an expression. It is often used as a cleaner alternative to multiple if-else statements. You may be asking yourself why use the switch statement since we already have if-else.
There are differences though. And depending on the task-at-hand, the switch statement can be a better alternative than if-else.
Structure:
switch (expression) {
case value1:
// execute this code block only
break;
case value2:
// execute this code block only
break;
default:
// execute if no cases match
}
A switch statement evaluates an expression and executes the code block for the first case that matches its value.
The break keyword is crucial. When encountered, it exits the entire switch statement immediately. Without it, execution will "fall through" and run the code in the subsequent case, even if the value doesn't match. If no matching case is found, the optional default block is executed.
Example:
let day = 'Monday';
let output = '';
switch (day) {
case 'Monday':
output = `Day is Monday`;
case 'Tuesday':
output = `Day is Tuesday`;
break;
case 'Wednesday':
output = `Day is Wednesday`;
break;
case 'Thursday':
output = `Day is Thursday`;
break;
case 'Friday':
output = `Day is Friday`;
break;
case 'Saturday':
output = `Day is Saturday`;
break;
case 'Sunday':
output = `Day is Sunday`;
break;
default:
output = `No day specified`;
}
// Output if day == 'Monday' OR day == 'Tuesday':
// Day is Tuesday
// Output if day == 'Saturday':
// Day is Saturday
// Output if day == 'Nothing'
// No day specified
This example demonstrates a crucial concept in JavaScript's switch statement: fallthrough. When day is 'Monday', the output will indeed be "Day is Tuesday". Here’s why: The switch statement finds a match on case 'Monday' and begins executing the code on the next line, setting output = 'Day is Monday'.
Because there is no break keyword at the end of the 'Monday' case, the logic "falls through" and continues to execute the very next line of code, which is the start of the 'Tuesday' case. It then executes output = 'Day is Tuesday', overwriting the previous value. Finally, the break keyword at the end of the 'Tuesday' case is encountered, which halts the execution of the switch block entirely.
The break statement is not optional for most use cases. It is essential for exiting the switch block once a specific case's code has finished running. Without it, execution will continue into the next case, whether it matches or not.
The default case is only executed if no other case values match the expression. It will not be executed simply because of a fallthrough from a matched case (unless that fallthrough leads all the way to it).
What is the PHP Spread Operator (...)
Spread Operator (...)
The PHP Spread Operator (...) is a powerful feature introduced in PHP 5.6 that allows you to "unpack" or "spread" elements from arrays and traversable objects. It's also known as the splat operator or unpacking operator.
The spread operator is particularly useful in modern PHP development for creating more expressive and efficient code when working with arrays and variable function arguments.
Key Benefits of the PHP Spread Operator
-
Cleaner syntax for array merging and function calls
-
Better performance in some cases compared to array_merge()
-
More readable code when dealing with multiple arrays
-
Flexible for both array operations and function arguments
Here are a few common use cases for the operator:
Unpack and Merge Multiple Arrays
Here are a couple of examples for unpacking and merging arrays.
$array1 = [1, 2, 3];
$array2 = [4, 5, 6];
$array3 = [7, 8, 9];
$merged = [...$array1, ...$array2, ...$array3];
// Array (
// [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5
// [5] => 6 [6] => 7 [7] => 8 [8] => 9
// )
$original = ['b', 'c', 'd'];
$newArray = ['a', ...$original, 'e'];
// Array (
// [0] => a [1] => b [2] => c [3] => d [4] => e
// )
Function Arguments
// FUNCTION ARGUMENTS
function addNumbers($a, $b, $c) {
return $a + $b + $c;
}
$numbers = [2, 4, 6];
$result = addNumbers(...$numbers);
echo $result; // Output: 12
function sum(...$numbers) {
return array_sum($numbers);
}
$values = [1, 2, 3, 4, 5];
echo sum(...$values); // Output: 15
Combining With Regular Elements
// Combining with Regular Elements
$first = [1, 2];
$last = [5, 6];
$combined = [...$first, 3, 4, ...$last];
print_r($combined);
// Output: Array ([0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6)
Usage With Associative Arrays
Notice that array keys are also considered making it perfect for merging associative arrays as well.
//With Associative Arrays
$config1 = ['host' => 'localhost', 'port' => 3306];
$config2 = ['username' => 'root', 'password' => 'secret'];
$finalConfig = [...$config1, ...$config2];
print_r($finalConfig);
// Output: Array ([host] => localhost [port] => 3306 [username] => root [password] => secret)
String To Array Conversion
// String To Array Conversion
$string = "hello";
$chars = [...$string];
print_r($chars);
// Output: Array ([0] => h [1] => e [2] => l [3] => l [4] => o)
Practical Example of Merging 2 Configuration Arrays
Remember that when merging 2 associative arrays using the spread operator and brackets syntax, the second array in the will overwrite values with matching keys. Take a look at the ‘debug’ key below:
// Configuration Merging
$defaultConfig = [
'debug' => false,
'cache' => true,
'timeout' => 30
];
$userConfig = [
'debug' => true,
'database' => 'mysql'
];
$finalConfig = [...$defaultConfig, ...$userConfig];
print_r($finalConfig);
// Output: Array ([debug] => true [cache] => true [timeout] => 30 [database] => mysql)
Format Date and Time in JavaScript with Date Object
This tutorial The JavaScript Date library is a built-in object that represents a single moment in time. It provides methods for creating, parsing, formatting, and manipulating dates and times. Dates are stored as the number of milliseconds since the Unix epoch (January 1, 1970, 00:00:00 UTC).
In this tutorial I will cover how to format date only, time only, and both date and time using these 3 methods from built-in object Date. A method to format a date. A method to format a time. And a method to format both date and time.
const date = new Date('2025-10-23 11:06:48');
date.toLocaleDateString('en-US');
date.toLocaleTimeString('en-US');
date.toLocaleString('en-US');
Also, I have included 2 handy references at the end of this tutorial. A reference for options and values available to define the format. Also, a reference that lists all available methods on the Javascript built-in Date object.
Date toLocaleDateString()
The toLocaleDateString() method formats the date only. Below the value of the date will be initiated as datetime (yyyy-mm-dd hh:mm:ss):
const date = new Date('2025-10-23 11:06:48');
Even though the Date object is initiated with a date and time string, only the date part of the string will be extracted. The default date.toLocaleDateString('en-US') returns the date formatted as mm/dd/yyyy. Also use other formatting options available. The options are referenced below.
const date = new Date('2025-10-23 11:06:48');
// Date only
date.toLocaleDateString('en-US');
// "10/23/2025"
date.toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
// "October 23, 2025"
Date toLocaleTimeString()
Target and format the time portion of the string using toLocaleTimeString(). Now time is extracted from the initial value set below…
const date = new Date('2025-10-23 11:06:48');
The toLocaleTimeString() method can be used with or without options. The default time is in 12 hour format (hh:mm:ss AM/PM). Options are listed below:
// Time only
date.toLocaleTimeString('en-US');
// "11:06:48 AM"
date.toLocaleTimeString('en-US', {
hour: '2-digit',
minute: '2-digit',
hour12: true
});
// "11:06 AM"
Date toLocaleString()
To format both the date and time use toLocaleString(). This method also accepts options to provide formatting instructions. Refer to the list below.
// Combined date and time
date.toLocaleString('en-US');
// "10/23/2025, 11:06:48 AM"
date.toLocaleString('en-US').replace(/,/g, '');
// "10/23/2025 11:06:48 AM"
Below are all the possible format options that can be passed to toLocaleString() for the en-US locale.
Option Reference Table toLocaleString()
|
Parameter |
Possible Values |
Description |
Example Output |
|
DATE COMPONENTS |
|||
|
year |
'numeric' |
Full year |
2025 |
|
'2-digit' |
Two-digit year |
25 |
|
|
month |
'numeric' |
Month number |
10 |
|
'2-digit' |
Two-digit month |
10 |
|
|
'long' |
Full month name |
October |
|
|
'short' |
Abbreviated month |
Oct |
|
|
'narrow' |
Single character |
O |
|
|
day |
'numeric' |
Day of month |
23 |
|
'2-digit' |
Two-digit day |
23 |
|
|
weekday |
'long' |
Full weekday name |
Thursday |
|
'short' |
Abbreviated weekday |
Thu |
|
|
'narrow' |
Single character |
T |
|
|
TIME COMPONENTS |
|||
|
hour |
'numeric' |
Hour |
11 |
|
'2-digit' |
Two-digit hour |
11 |
|
|
minute |
'numeric' |
Minute |
6 |
|
'2-digit' |
Two-digit minute |
06 |
|
|
second |
'numeric' |
Second |
48 |
|
'2-digit' |
Two-digit second |
48 |
|
|
fractionalSecondDigits |
1, 2, 3 |
Milliseconds digits |
48.123 |
|
TIME SETTINGS |
|||
|
hour12 |
true |
12-hour clock |
11:06 AM |
|
false |
24-hour clock |
11:06 |
|
|
timeZone |
'America/New_York' |
Specific timezone |
Adjusts time |
|
'UTC' |
UTC timezone |
||
|
'Europe/London' |
Other timezones |
||
|
timeZoneName |
'short' |
Abbreviated timezone |
EDT |
|
'long' |
Full timezone name |
Eastern Daylight Time |
|
|
'shortOffset' |
Short offset |
GMT-4 |
|
|
'longOffset' |
Long offset |
GMT-04:00 |
|
|
'shortGeneric' |
Generic short |
ET |
|
|
'longGeneric' |
Generic long |
Eastern Time |
|
|
OTHER OPTIONS |
|||
|
era |
'long' |
Full era name |
Anno Domini |
|
'short' |
Abbreviated era |
AD |
|
|
'narrow' |
Single character |
A |
|
|
dayPeriod |
'narrow' |
AM/PM format |
AM |
|
'short' |
AM/PM format |
AM |
|
|
'long' |
AM/PM format |
AM |
|
|
calendar |
'gregory' |
Gregorian calendar |
Default |
|
numberingSystem |
'latn' |
Latin digits |
0123456789 |
|
PRESET STYLES |
|||
|
dateStyle |
'full' |
Complete date |
Thursday, October 23, 2025 |
|
'long' |
Long format |
October 23, 2025 |
|
|
'medium' |
Medium format |
Oct 23, 2025 |
|
|
'short' |
Short format |
10/23/2025 |
|
|
timeStyle |
'full' |
Complete time |
11:06:48 AM Eastern Daylight Time |
|
'long' |
Long format |
11:06:48 AM EDT |
|
|
'medium' |
Medium format |
11:06:48 AM |
|
|
'short' |
Short format |
11:06 AM |
JavaScript Date Library Function Reference
Constructor Methods
|
Method |
Description |
Example |
|
new Date() |
Current date/time |
new Date() |
|
new Date(milliseconds) |
From milliseconds since epoch |
new Date(1634980000000) |
|
new Date(dateString) |
From ISO string |
new Date("2025-10-23") |
|
new Date(year, month, day, hours, minutes, seconds, ms) |
From components |
new Date(2025, 9, 23) |
Static Methods
|
Method |
Description |
Returns |
|
Date.now() |
Current timestamp in milliseconds |
1634980000000 |
|
Date.parse() |
Parse date string to milliseconds |
1634980000000 |
|
Date.UTC() |
UTC timestamp from components |
1634980000000 |
Getter Methods: Local Time Getters
|
Method |
Description |
Range |
|
getFullYear() |
4-digit year |
1900+ |
|
getMonth() |
Month |
0-11 |
|
getDate() |
Day of month |
1-31 |
|
getDay() |
Day of week |
0-6 |
|
getHours() |
Hours |
0-23 |
|
getMinutes() |
Minutes |
0-59 |
|
getSeconds() |
Seconds |
0-59 |
|
getMilliseconds() |
Milliseconds |
0-999 |
|
getTime() |
Milliseconds since epoch |
0+ |
|
getTimezoneOffset() |
Timezone offset in minutes |
-720 to 720 |
UTC Getters
|
Method |
Description |
Range |
|
getUTCFullYear() |
UTC 4-digit year |
1900+ |
|
getUTCMonth() |
UTC month |
0-11 |
|
getUTCDate() |
UTC day of month |
1-31 |
|
getUTCDay() |
UTC day of week |
0-6 |
|
getUTCHours() |
UTC hours |
0-23 |
|
getUTCMinutes() |
UTC minutes |
0-59 |
|
getUTCSeconds() |
UTC seconds |
0-59 |
|
getUTCMilliseconds() |
UTC milliseconds |
0-999 |
Setter Methods
Local Time Setters
|
Method |
Description |
Parameters |
|
setFullYear() |
Set year |
year[, month, day] |
|
setMonth() |
Set month |
month[, day] |
|
setDate() |
Set day of month |
day |
|
setHours() |
Set hours |
hours[, min, sec, ms] |
|
setMinutes() |
Set minutes |
minutes[, sec, ms] |
|
setSeconds() |
Set seconds |
seconds[, ms] |
|
setMilliseconds() |
Set milliseconds |
ms |
|
setTime() |
Set time via milliseconds |
milliseconds |
UTC Setters
|
Method |
Description |
Parameters |
|
setUTCFullYear() |
Set UTC year |
year[, month, day] |
|
setUTCMonth() |
Set UTC month |
month[, day] |
|
setUTCDate() |
Set UTC day of month |
day |
|
setUTCHours() |
Set UTC hours |
hours[, min, sec, ms] |
|
setUTCMinutes() |
Set UTC minutes |
minutes[, sec, ms] |
|
setUTCSeconds() |
Set UTC seconds |
seconds[, ms] |
|
setUTCMilliseconds() |
Set UTC milliseconds |
ms |
Conversion Methods
|
Method |
Description |
Example Output |
|
toString() |
Full date string |
"Thu Oct 23 2025 11:06:48 GMT-0400 (EDT)" |
|
toDateString() |
Date portion only |
"Thu Oct 23 2025" |
|
toTimeString() |
Time portion only |
"11:06:48 GMT-0400 (EDT)" |
|
toISOString() |
ISO 8601 format |
"2025-10-23T15:06:48.000Z" |
|
toUTCString() |
UTC string |
"Thu, 23 Oct 2025 15:06:48 GMT" |
|
toGMTString() |
GMT string (deprecated) |
"Thu, 23 Oct 2025 15:06:48 GMT" |
|
toJSON() |
JSON string |
"2025-10-23T15:06:48.000Z" |
|
toLocaleString() |
Locale date/time |
"10/23/2025, 11:06:48 AM" |
|
toLocaleDateString() |
Locale date only |
"10/23/2025" |
|
toLocaleTimeString() |
Locale time only |
"11:06:48 AM" |
Value Methods
|
Method |
Description |
Returns |
|
valueOf() |
Primitive value |
Milliseconds (same as getTime()) |
A Quick HowTo of PHP Operators
Math Operators
Addition:
Caculate the sum of two numbers using the + operator.
$sum = 1 + 3;
The value of $sum is 4.
Subtraction:
Caculate the difference of two numbers using the - operator.
$diff = 3 - 2;
The value of $diff is 1.
Division:
Calculate the quotient of two numbers using the / operator.
$quotient = 4 / 2;
The value of $quotient is 2.
Multiplication:
Calculate the product using the * operator.
$product = 4 * 5;
The value of $product is 20.
Modulo:
Gives the remainder after dividing two numbers the % operator.
$remainder = 10 % 3;The value of $remainder is 1.
How to Backup and Restore with pg_dump and mysqldump
This tutorial guides you through backing up MySQL and PostgreSQL databases from the command line. While their native tools—mysqldump and pg_dump—share a similar purpose, their command syntax differs. We will cover the essential commands for both systems, highlighting their key similarities and differences.
Backup MySQL / MariaDB Database
Export every table’s schema and existing records to an SQL executable script.
mysqldump -u username -p database_name > database.sql
This will export the specified table’s schema and records to an executable script.
mysqldump -u username -p database_name table_name > db_table.sql
This will export the specified table’s data only(no schema).
mysqldump -u username -p --no-create-info database_name table_name > table_data.sql
This will export the specified table’s schema only(no data).
mysqldump -u username -p --no-data database_name table_name > table_schema.sql
Restore MySQL / MariaDB Database
mysql -u username -p database_name < database.sql
Backup PostgreSQL Database
Export every table’s schema and existing records to an SQL executable script.
pg_dump -U username database_name > database.sql
This will export both the specified table’s schema and data to an executable script.
pg_dump -U username -t table_name database_name > table.sql
Only data (no schema):
pg_dump -U username -a -t table_name database_name > table_data.sql
Only schema (no data):
pg_dump -U username -s -t table_name database_name > table_schema.sql
Restore PostgreSQL Database
psql -U username -d database_name -f database.sql