I’ve been challenged to start the #100DayCodeChallenge, and guess what?! Challenge Accepted!! So for the next 100 days, I’ll be sharing my knowledge, learning, and experiences.
Below is my progress from previous days, and I’ll now be updating regularly from today. If you’re up for it, join me on this adventure!
Imagine you order a pizza, so the process can be broken into several steps: You call the bakery and place an order for a pizza, then the bakery confirms your order and gives you an estimated delivery time. At this point, a promise is created and it is in the “pending” state. During this time, you’re waiting for the pizza to be delivered, and you don’t know if it will arrive on time, be delayed, or if there might be an issue with the bakery. So, the promise is still in the “pending” state. Now, there are two cases: if the pizza arrives (order is fulfilled), the promise is fulfilled. If there is an issue with the bakery and the pizza doesn’t arrive (order is rejected), the promise is rejected.
In this code:
A function called orderPizza is created that returns a new Promise, so this promise starts in the “pending” state.
The setTimeout function is used to simulate the wait time for the pizza delivery. This represents the period during which the promise is pending.
After 2 seconds, a random boolean value called isPizzaDelivered determines whether the pizza is delivered or not:
If the boolean is true, the promise is resolved by calling resolve, so the promise is moved to the “fulfilled” state.
If the boolean is false, the promise is rejected by calling reject, and the promise is moved to the “rejected” state.
The then method is used to handle the case when the promise is fulfilled, while the catch method is used to handle the case when the promise is rejected.
As a result, a Promise is an object that represents the eventual completion (or failure) of an asynchronous operation and its resulting value. Promises provide a way to handle asynchronous operations more efficiently than traditional callback-based approaches. 100daysofcodelebanon-mug
BSON (Binary JSON) is a binary-encoded serialization format that is used to store documents and make remote procedure calls in MongoDB. It extends the JSON model to provide additional data types and to be efficient for encoding and decoding within different languages.
In BSON: \x16\x00\x00\x00\x02name\x00\x08\x00\x00\x00John Doe\x00\x10age\x00\x1e\x00\x00\x00\x03address\x00\x3d\x00\x00\x00\x02street\x00\x09\x00\x00\x00123 Elm St\x00\x02city\x00\x09\x00\x00\x00Somewhere\x00\x02state\x00\x03\x00\x00\x00CA\x00\x00\x04phones\x00\x1f\x00\x00\x00\x020\x00\x0c\x00\x00\x00123-456-7890\x0001\x00\x0c\x00\x00\x00987-654-3210\x00\x00\x08isActive\x00\x01\x00\x00\x00
As a result:
Using BSON, MongoDB combines the flexibility of JSON with the efficiency of binary encoding, making it a robust solution for handling large and complex datasets. 100daysofcodelebanon-mug
Day 3: Arrow Functions
Arrow functions in JavaScript are a concise syntax for writing function expressions.
How to implement it?
1-Simple Arrow Functions: const addArrow = (x, y) => x + y;
2-Arrow Function with single parameter: const squareArrow = x => x * x;
3-Arrow Function with no parameters: const greetArrow = () => 'Hello, world!';
A Blob (Binary Large Object) in JavaScript represents raw binary data, like images or files. It’s often used to handle and store large amounts of data, allowing web applications to read, save, and send this data efficiently.
In this code, first, the JSON data is converted into a string using JSON.stringify(). Then, this stringified JSON data is used to create a Blob with a JSON file.
Node.js is a powerful JavaScript runtime built on Chrome’s V8 engine. It allows developers to run JavaScript on the server-side, enabling the creation of fast and scalable network applications. Here’s why Node.js is so popular:
Asynchronous and Event-Driven: Node.js is designed to handle many connections simultaneously, making it ideal for building real-time applications like chat servers, online gaming, and live streaming.
Single Programming Language: Use JavaScript for both client-side and server-side development, streamlining your development process.
NPM Ecosystem: Node.js comes with the Node Package Manager (NPM), which hosts thousands of reusable packages and libraries, making development faster and easier.
Local Storage is a web storage feature that allows you to store data in the browser. Unlike cookies, the storage limit is much larger (typically around 5MB) and the data is not sent to the server with every request.
Why Use Local Storage?
Persistence: Data remains stored even after the browser is closed and reopened.
Capacity: Can store more data compared to cookies.
Simple API: Easy to use with a straightforward API.
Basic Usage of Local Storage
Here’s how you can use Local Storage to store, retrieve, and remove data:
Storing Data
To store data, use the setItem method. The data is stored as a key-value pair.
// Store a string
localStorage.setItem('name', 'John Doe');
Retrieving Data
To retrieve data, use the getItem method. Remember to parse it back to an object if it was stored as a JSON string.
// Retrieve a string
const name = localStorage.getItem('name');
console.log(name); // Outputs: John Doe
Removing Data
To remove data, use the removeItem method.
localStorage.removeItem('name');
Clearing All Data
To clear all data stored in Local Storage, use the clear method.
localStorage.clear();
As a conclusion, Local Storage is a powerful feature for storing data on the client side. 100daysofcodelebanon-mug
Imagine you are managing an online bookstore, and your MongoDB database has a collection named books to store information about each book. Here’s how indexes can help improve the performance of various queries.
The books Collection
Each document in the books collection might look something like this:
{
"_id": "1",
"title": "JavaScript: The Good Parts",
"author": "Douglas Crockford",
"year": 2008
}
Common Query and How Indexes Help
Finding a Book by Title
Query:
db.books.find({ title: "JavaScript: The Good Parts" });
Without an Index: MongoDB scans every document in the books collection to find the match, which can be slow if there are thousands of books.
With a Single Field Index: Create an index on the title field:
db.books.createIndex({ title: 1 });
This index allows MongoDB to quickly locate books by title, significantly speeding up the query.
Regular Expressions, commonly known as RegEx, are patterns used to match character combinations in strings. In JavaScript, RegEx provides powerful pattern-matching capabilities that allow you to search, replace, and validate text efficiently.
Why Use RegEx?
Validation: Validate input fields, such as email addresses, phone numbers, and passwords.
Searching: Search for specific patterns within strings.
Replacing: Replace occurrences of a pattern with a new substring.
Extracting: Extract substrings that match a pattern.
How to Create a RegEx?
There are two ways to create a RegEx in JavaScript:
Using literal notation:
const pattern = /abc/;
Using the RegExp constructor:
const pattern = new RegExp('abc');
There are several methods that RegEx use such as test, exec, match, replace, split… each has its usage
Session Storage is a type of web storage that allows you to store data for the duration of a page session. This means the data is accessible only while the browser is open and the page session is active. Once the browser is closed, the data is cleared.
Basic Operations
Storing Data
To store data in session storage, use the setItem method:
The Fetch API is a modern, promise-based approach to making network requests in JavaScript. It provides an easy and flexible way to interact with RESTful services and fetch resources across the web.
Why Use the Fetch API?
Simplicity: Easy to use with a clean and straightforward syntax.
Promises: Uses promises, allowing for better control over asynchronous operations.
Compatibility: Supported in all modern browsers.
Basic Usage
Making a GET Request
To fetch data from a server, use the fetch function:
Asynchronous JavaScript allows you to perform long-running tasks, like fetching data from an API, without blocking the main thread. This makes your web applications more responsive and user-friendly.
Why Use Async/Await?
Simplified Syntax: Async/await provides a cleaner and more readable way to work with promises compared to chaining .then() and .catch() methods.
Error Handling: Easier error handling using try...catch blocks.
Sequential Execution: Allows for writing asynchronous code that looks and behaves like synchronous code.
How to Use Async/Await
Defining an Async Function
An async function is declared using the async keyword before the function definition:
async function fetchData() {
// Code inside here is asynchronous
}
Using await
The await keyword pauses the execution of the async function until the promise is resolved:
Day 13: *** Responsive Design with CSS Media Queries***
What are Media Queries?
Media queries are a powerful feature in CSS that allow you to create responsive designs. They enable your web pages to adapt to different screen sizes, orientations, and resolutions, ensuring a consistent and user-friendly experience across devices.
Why Use Media Queries?
Responsive Design: Tailor your layouts and styles for various screen sizes, from mobile phones to large desktops.
Optimized User Experience: Improve usability by adjusting the design based on the user’s device.
Future-Proofing: Prepare your website to handle new devices and screen sizes as technology evolves.
Example
Imagine you’re designing a website with a navigation menu that should look different on mobile and desktop. With media queries, you can hide the desktop menu on mobile and show a hamburger menu instead:
/* Desktop Menu */
.nav-menu {
display: flex;
}
/* Mobile Menu */
@media (max-width: 768px) {
.nav-menu {
display: none;
}
.hamburger-menu {
display: block;
}
}
The spread operator (...) in JavaScript is a powerful tool that allows you to expand arrays and objects into individual elements or properties. It simplifies the way you handle data structures, making your code more readable and concise.
How Does the Spread Operator Work?
Copying Arrays
Create a new array that’s an exact copy of another:
Day 15: Using pre-save middleware in MongoDB with Mongoose
What is pre-save middleware?
In MongoDB, when using Mongoose as an Object Data Modeling (ODM) library, the pre-save middleware is a powerful tool that allows you to execute custom logic right before a document is saved to the database. This is incredibly useful for tasks like data validation, hashing passwords, or updating timestamps automatically.
The pre-save middleware in Mongoose is an essential feature for anyone working with MongoDB. It gives you control over your data by allowing you to execute custom logic before saving documents.
MongoDB offers a range of powerful query functions that allow you to efficiently find, filter, and manipulate data within your collections. Whether you’re retrieving a single document or filtering complex datasets, these functions are your go-to tools for interacting with your database.
Key Query Functions
find()
findOne()
findById()
findOneAndDelete()
findOneAndUpdate()
Why Use MongoDB Query Functions?
Efficient Data Retrieval: Quickly find and filter the exact data you need.
Powerful Data Manipulation: Update, insert, and delete documents with ease.
Advanced Aggregation: Perform complex calculations and transformations directly within the database.
Stay tuned as we dive into each of these functions in upcoming posts!
The find() function in MongoDB is your go-to method for retrieving multiple documents from a collection. It allows you to filter through your data and return exactly what you need, making it an essential tool for working with MongoDB.
How It Works
The find() function can retrieve all documents or filter documents based on specific criteria. It returns a cursor, which you can iterate over to access the documents.
Example Usage
Let’s say you have a collection of users, and you want to find all users who have an active status:
users.find({ status: 'active' })
What It Does
Filter Data: Only documents where the status field is 'active' will be returned.
Flexible Queries: You can combine multiple conditions to narrow down your search.
Returns a Cursor: This allows you to efficiently iterate through large datasets.
Pro Tip:
You can further refine your query by adding projection, sorting, or limiting the results:
Day 18: *** findOne() Query Function in MongoDB***
Exploring the findOne() Query Function
The findOne() function in MongoDB is perfect when you need to retrieve a single document from a collection. It’s designed to return the first document that matches your query criteria, making it efficient and straightforward.
How It Works
Unlike the find() function, which returns multiple documents, findOne() stops searching after finding the first match. This is ideal when you’re looking for a unique record or just need a quick lookup.
Example Usage
Imagine you have a collection of users, and you want to find the user with a specific username:
users.findOne({ username: 'baqer_qabalan' })
What It Does
Single Document Retrieval: Fetches the first document that matches the query criteria.
Simplicity: No need to iterate through results; you get the document directly.
Efficient Searches: Quickly locates the desired document without scanning the entire collection.
Pro Tip:
You can also combine findOne() with projection to retrieve only specific fields from the document:
The findById() function in MongoDB is a powerful and convenient method for retrieving a single document based on its unique _id. This function simplifies the process of fetching documents by their unique identifier, ensuring you get the exact record you need with minimal effort.
How It Works
Every document in MongoDB has a unique _id field, which acts as a primary key. The findById() function leverages this to quickly locate and return the document associated with a specific _id value.
Example Usage
Suppose you have a user collection, and you want to find a user by their unique ID: