Let's continue our exploration of data sets in JavaScript by having a look at the objects!
An object is also a collection of data but in a structured way as it's stored by pairs of property (or key) / value. For instance:
const BOOK = {
title: "The Lord of the Rings",
"volumes": 3,
"main characters": ["Frodo", "Aragorn"],
9: ["Fellows", "Nazgul"]
};
Notes:
To access the propertie's value, you can either use the dot or the bracket notation:
const TITLE = BOOK.title;
const VOLUMES = BOOK["volumes"];
const MAIN_CHARACTERS = BOOK["main characters"];
const NINE = BOOK[9]
You can use the dot notation if your property in a string of a single word. Otherwise, user the bracket notation with quotes for strings and without for numbers.
Tip: not sure a property exists? Use optionnal chaining (?.)! It helps prevent errors when accessing nested properties that might be null or undefined.
console.log(BOOK?.isbn);
Properties stored as value of a variable can also be access with the bracket notation. For instance:
const MAIN_CHARACTERS = "main characters";
let charactersList = BOOK[MAIN_CHARACTERS];
console.log(charactersList);
will print
[ 'Frodo', 'Aragorn' ]
on the console.
This can be very useful for iterating through an object's properties.
The same principle applies to access to sub propertie's values, just continue to filter via bracket or dot notation until you reach your destination. For instance (from FreeCodeCamp):
const ourStorage = {
"desk": {
"drawer": "stapler"
},
"cabinet": {
"top drawer": {
"folder1": "a file",
"folder2": "secrets"
},
"bottom drawer": "soda"
}
};
ourStorage.cabinet["top drawer"].folder2; // returns string "secrets"
ourStorage.desk.drawer; // returns string "stapler"
To check if the property of a given object exists or not, use the .hasOwnProperty(propname) method. It returns true or false if the property is found or not. For instance:
BOOK.hasOwnProperty("title");
BOOK.hasOwnProperty("author");
The first hasOwnProperty returns true, while the second returns false.
Note: always use quotes for string properties, otherwise an error is thrown.
Use Object.keys() method. It takes an object as the argument and returns an array of strings representing each property in the object. The order is first all non-negative integer keys in ascending order by value, then other string keys in ascending chronological order of property creation. For instance:
Object.keys(BOOK) // returns [ '9', 'title', 'volumes', 'main characters' ]
Same principle. Use Object.values() method.
Object.values
(BOOK) // returns [ [ 'Fellows', 'Nazgul' ], 'The Lord of the Rings', 3, [ 'Frodo', 'Aragorn' ] ]
Same principle. Use Object.entries() method.
Object.entries
(BOOK) //returns [ [ '9', [ 'Fellows', 'Nazgul' ] ], [ 'title', 'The Lord of the Rings' ], [ 'volumes', 3 ], [ 'main characters', [ 'Frodo', 'Aragorn' ] ] ]
Use a for...in statement. It looks like this:
for (let item in BOOK) {
console.log(item);
} // logs 9, title, volumes, main characters, each value in its own line
Here, "item" is a variable we define - it could be any name. Its value will change at each iteration.
The example comes from FreeCodeCamp.
Consider this object:
const user = { name: 'John Doe', age: 34 };
To extract both values and assign them to variables you could use:
const { name, age } = user;
Read it as: "create constants named "name" and "age" containing values from "name" and "age" properties in "user" object". This is a shorthand equivalent of
const name = user.name;
const age = user.age;
A console.log on name and age would return John Doe and 34, each on its own line
const declaration can by bypassed. To protect data from mutation, use Object.freeze() function. The argument would be the object you'd like to freeze. For instance (from FreeCodeCamp):
let obj = {
name:"FreeCodeCamp",
review:"Awesome"
};
Object.freeze(obj);
obj.review = "bad";
obj.newProp = "Test";
obj.review and obj.newProp assignments will result in errors and the object wouldn't change.
Proceed like any other variable; using dot or bracket notation. For instance:
BOOK["main characters"][1] = "Sam";
BOOK["main characters"][2] = "Bill";
console.log(BOOK["main characters"]);
will print
[ 'Frodo', 'Sam', 'Bill' ]
on the console.
Proceed just like you would for updating. For instance:
BOOK.format = "";
BOOK["number of copies"] = 100;
BOOK[5] = "Hello";
BOOK object will now look like this:
{
'5': 'Hello', '9': [ 'Fellows', 'Nazgul' ], title: 'The Lord of the Rings', volumes: 3, 'main characters': [ 'Frodo', 'Aragorn' ],
format: '', 'number of copies': 100
}
Order has not much importance from an object perspective because you're not using indexes to access data. But if this is important, consider using the spread operator (I'll probably write a blog entry later on this subject). Note that number properties order themselves at the beginning of the object.
User the delete keyword and then target your property according to it's format. For instance:
delete BOOK.format;
delete BOOK["number of copies"];
delete BOOK[5];
This is a personal step by step procedure to be updated.
cd Documents/www/project
git init
git add .
git commit -m "initial commit"
git remote add origin URL
git push -u origin master
cd Documents/www/project
git add .
git commit -m "changed this"
git remote add master URL
git push -u master
I learned a few things about JavaScript on OpenClassrooms (taking Apprenez à programmer avec JavaScript & Écrivez du JavaScript pour le web courses). I didn't know it then but I was actually looking for DOM manipulation for my Qwixx project. Anyway, I'm refreshing my newbie knowledge by taking FreeCodeCamp JavaScript Algorithms and Data Structures course and here is a recap about arrays.
An array can store multiple pieces of data in a single variable. Each entry is separated by a comma and nested into square brackets. Just like this:
const SANDWICH = ["peanut butter", 1, true, ["bakery", "home-made"]];
An array containing another array is also called a multi-dimensional array. An array can also contain objects.
"peanut butter" | 1 | true | ["bakery", "home-made"] |
0 | 1 | 2 | 3 |
Arrays use zero-based indexing, so the first element in an array has an index of 0. Use square bracket notation to get the data associated to the index. For instance:
console.log(SANDWICH[0]);
const EATEN = SANDWICH[1];
console.log(EATEN);
will print "peanut butter" string and 1 number.
Additional pair of brackets refers to the next level of entries inside.
const BOUGHT_IN = SANDWICH[3][0];
console.log(BOUGHT_IN);
will print "bakery"
.
JavaScript handles associative arrays
let currencies = [];
currencies["EUR"] = "Euro";
currencies["USD"] = "American dollar";
console.log(currencies); // [EUR: 'Euro', USD: 'American dollar']
Use indexOf() method. It returns -1 if the item is not found. For instance:
SANDWICH.indexOf('peanut butter'); // returns 0
SANDWICH.indexOf('butter'); // returns -1
Use spread operator (...). For instance (from FreeCodeCamp):
const arr = [6, 89, 3, 45];
const maximus = Math.max(...arr); // maximus has the value of 89
Use a for loop. It looks like this:
let array = [1, 2, 3]
for (let i = 0; i < array.length; i++) {
console.log(array[i])
} // logs 1, 2, 3, each on its own line
Even if an array is defined as a const its entries are mutable. From our example,
SANDWICH[0] = "houmus";
SANDWICH now has the value
["houmus", 1, true, ["bakery", "home-made"]];
Use push() method. It takes one or more parameters and "pushes" them onto the end of an array. For instance:
const arr = [1, 2, 3];
arr.push(4);
arr now has the value [1, 2, 3, 4]
Use unshift() method. For instance:
const arr = [1, 2, 3];
arr.unshift(0);
arr now has the value [0, 1, 2, 3]
Use splice() method.
First argument: the index at which to begin deleting elements
Second argument (optional): the number of elements to be deleted
Third argument (optional): items to insert starting at that same index, searated by a comma
For instance (example from FreeCodeCamp):
const numbers = [10, 11, 12, 12, 15];
const startIndex = 3;
const amountToDelete = 1;
numbers.splice(startIndex, amountToDelete, 13, 14);
console.log(numbers); // returns [ 10, 11, 12, 13, 14, 15 ]
User spread operator (...). For instance (example from FreeCodeCamp):
let arrayToAppend = ['sage', 'rosemary', 'parsley', 'thyme'];
let mainArray = ['basil', 'cilantro', ...arrayToAppend, 'coriander'];
mainArray now has the value ['basil', 'cilantro', 'sage', 'rosemary', 'parsley', 'thyme', 'coriander']
Use pop() method. For instance:
const arr = [1, 2, 3];
arr.pop();
arr now has the value [1, 2]
Use shift() method. For instance:
const arr = [1, 2, 3];
arr.shift();
arr now has the value [2, 3]
Note: removed data can be returned if assigned to a variable. For instance:
const arr = [1, 2, 3];
let removedNumber = arr.pop();
let one = arr.shift();
removedNumber has the number 3 as a value and one, 1
You can also use splice() method!
First argument: the index at which to begin deleting elements
Second argument (optional): the number of elements to be deleted
For instance (from FreeCodeCamp):
let array = ['today', 'was', 'not', 'so', 'great'];
array.splice(2, 2); // array now has the value ['today', 'was', 'great']
Here we remove 2 elements, beginning with the third element (at index 2). array would have the value
Note: removed data can be returned if assigned to a variable.
I realized it was not working like classic variables like these:
let a = "first variable"; // a contains "first variable" string
let b = a; // a and b contain "first variable" string
b = "second variable"; // a contains "first variable" and b "second variable" string
let array1 = [1, 2, 3]; // array1 contains [1, 2, 3] array
let array2 = array1; // array1 and array2 contain [1, 2, 3] array
array2.unshift(0); // array1 and array2 contain [0, 1, 2, 3] array
Here, array2 behaves just like another pointer to the same object. Modifying array2 will modify array1 and inversely. So how can we copy an array? Here are several methods:
For instance:
let originalArray = ['great', 'awesome', 'super', 'wonderful'];
let copiedArray = [...originalArray];
originalArray remains unchanged and copiedArray has the same elements as originalArray.
With slice() method, we can copy or extract a given number of elements to a new array, leaving the original array unchanged. It takes 2 parameters:
First argument: the index at which to begin extraction
Second argument (optional): the index at which to stop extraction (not included)
For instance (example from FreeCodeCamp):
let weatherConditions = ['rain', 'snow', 'sleet', 'hail', 'clear'];
let todaysWeather = weatherConditions.slice(1, 3); // todaysWeather is ['snow', 'sleet']
some() methods accepts a callback function which should take an element of the array as the argument. It will will return true
if the callback function returns true
for at least one element in the array.
Again, this article has to do with understanding default display value before attempting changes. An HTML element could be either inline or block.
Most used inline elements: a, img, br, span, input, label
Often used inline elements: button, code, em, strong, textarea, select
Most used block elements:
Change default display
Diplay can be decomposed in two directions: outer (element's participation in flow layout) and inner (sets layout of children).
Use display property and set it to block or inline - this defines outer direction
Depending on your intent, you may also want to consider using flex value to manage the inner direction
Note that you can use precomposed values containing both outer and then inner instructions such as inline-flex or inline-block.
Zoom on inline-block
Using inline-block you can transform a block element into an inline element, with a width set. Just remember that your two elements must be on the same line to fit into a 100% width. Use a wrapper to set space between elements. Full demo can be found on CodePen. In the following example, p elements will be displayed side by side.
CSS
p {
display: inline-block;
width: 50%;
}
HTML
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean nec neque ut dolor vehicula malesuada.</p><p>Aliquam ornare, orci elementum gravida congue, augue eros congue diam, nec vehicula velit velit non
orci. In eget sem nunc. Nulla facilisi.</p>
Forms are inevitable on a web journey. Here are some commented examples to understand each component
Table of contents:
Let's take this search field form (from How to transfigure wireframes into HTML by Lara Aigmüller) as an example.
form tag -> to open an area in the document where the user can provide information
action attribute -> indicates an URL where the form data should be sent. If omitted, it defaults to current page.
role attribute -> for accessibility purposes (value is search to identify search functionnality)
label tag -> to help associate the text for an input element with the input element itself (clicking on the text will select the corresponding button; helpful for assistive technologies)
for attribute -> association method with an input id where values are the same. Another method could be:
<label>
<input type="search" id="search-input" placeholder="Search…" name="q" />
Search articles
</label>
input tag -> allows several ways to collect data
type attribute -> many possible values, see below
id attribute -> the most important attribute in the universe. Used to identify specific HTML elements. Each id attribute's value must be unique from all other id values for the entire page.
placeholder attribute -> used to give people a hint about what kind of information to enter into an input but this is actually not a best-practice for accessibility (users can confuse the placeholder text with an actual input value).
name attribute -> value to represent the data being submitted, mandatory to be processed on the server-side. Helps grouping radio buttons (selecting one deselects the other - see survey form example).
value attribute -> initial value (for submit and button types: text that will display) - for instance ->
<form method="post" action="./contact">
<input id="name" type="text" name="name" value="" placeholder="Name" required>
<input id="email" type="email" name="email" value="" placeholder="Email" required>
<textarea id="message" rows="6" name="message" placeholder="Message" required></textarea>
<div data-sitekey="..."></div>
<button id="submit" name="submit" type="submit">Send email</button>
</form>
Let's take this contact form (from Bludit plugin) as an example.
form tag method attribute -> specifies how to send form-data
input tag required attribute -> data is mandatory to allow submission
div tag data-sitekey attribute -> I'll do some research on this topic later on. For now let's just say it's used to prevent spaming using CAPTCHA.
Question of the day: is there a "better" solution between button and input tag when type is submit? After some research I believe the answer is: no, functionnaly, it's identical. However, button elements are much easier to style and inner HTML content can be added. Note however that the first input element with a type of submit is automatically set to submit its nearest parent form element.
This is an example from FreeCodeCamp Responsive Web Design course:
<form action="https://freecatphotoapp.com/submit-cat-photo" target="_blank">
<fieldset>
<legend>Is your cat an indoor or outdoor cat?</legend>
<label>
<input id="indoor" type="radio" name="indoor-outdoor" value="indoor" checked> Indoor
</label>
<label>
<input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor
</label>
</fieldset>
<fieldset>
<legend>What's your cat's personality?</legend>
<input id="loving" type="checkbox" name="personality" value="loving" checked>
<label for="loving">Loving</label>
<input id="lazy" type="checkbox" name="personality" value="lazy">
<label for="lazy">Lazy</label>
<input id="energetic" type="checkbox" name="personality" value="energetic">
<label for="energetic">Energetic</label>
</fieldset>
<input type="text" name="catphotourl" placeholder="cat photo URL" required>
<button type="submit">Submit</button>
</form>
form tag, target attribute -> defines where to display the response after submitting the form. Default value is _self (ie current window)
fieldset tag -> used to group related inputs and labels together
legend tag -> acts as a caption for the content in the fieldset element
input tag
value atribute -> even if optionnal, it's best practice to include it with any checkboxes or radio buttons on the page. Otherwise, the form data would include name-value=on, which is not useful.
checked attribute -> force selection by default
button tag type attribute submit value -> note this is the default if the attribute is not specified for buttons associated with a <form>, or if the attribute is an empty or invalid value. button tag should always have a type attribute because different browsers may use different default types.
What type of input do you need?
min="2000-01-02"
)<input type="file" accept="image/*,.pdf">
<input type="button" value="Let's play!">
If type attribute is submit or image and if you want to proceed with a different action from the rest of the form with this input, use form+regularFormAttributeName to override form attributes for this specific button (ie formaction, formenctype, formmethod, formtarget, formnovalidate
<form action="/action_page.php">
<label for="fname">First name:</label>
<input type="text" id="fname" name="fname"><br><br>
<label for="lname">Last name:</label>
<input type="text" id="lname" name="lname"><br><br>
<input type="submit" value="Submit">
<input type="submit" formaction="/action_page2.php" formenctype="multipart/form-data" formmethod="post" formtarget="_blank" formnovalidate="formnovalidate" value="Submit as...">
</form>
Allow text edition on several lines. Use if you dare:
<textarea name="textarea" rows="10" cols="50">Please write here.</textarea>
Use for dropdown lists. Example from W3Schools:
<label for="cars">Choose a car:</label>
<select id="cars" name="cars" size="3" multiple>
<optgroup label="Swedish Cars">
<option value="volvo" selected>Volvo</option>
<option value="saab">Saab</option>
</optgroup>
<option value="fiat">Fiat</option>
<option value="audi">Audi</option>
</select>
selected attribute defines a pre-selected option.
size attribute defines the number of visible values
multiple attribute allow the selection of several options
Group options with optgroup element. Useful when lists are longs.
Specifies a list of pre-defined options for an input tag, showed depending on the user's input. Example from W3Schools:
<form action="/action_page.php">
<input list="browsers">
<datalist id="browsers">
<option value="Internet Explorer">
<option value="Firefox">
<option value="Chrome">
<option value="Opera">
<option value="Safari">
</datalist>
</form>
Represents the result of a calculation. Example from W3Schools:
<form action="/action_page.php" oninput="x.value=parseInt(a.value)+parseInt(b.value)">
0 <input type="range" id="a" name="a" value="50"> 100 +
<input type="number" id="b" name="b" value="50"> =
<output name="x" for="a b"></output>
<br/>
<input type="submit">
</form>
For form and input tags :valid and :invalid pseudo-classes
The end of year came so quickly I did not find the time to write a short recap. So here it is!
2023 expectations: friends & family being well; my wedding being happy
2023 expectations: none in particular
2023 expectations: publish one book
2023 expectations: continue, finish projects, earn certifications
2023 expectations: see how it goes with 1 night per month in Paris