JavaScript is a programming language that runs in web browsers and makes web pages interactive.
The Three Pillars of Web Development:
What Can JavaScript Do?
Three Ways to Include JavaScript:
1. Inline (Not Recommended):
<button onclick="alert('Hello!')">Click Me</button>
2. Internal Script:
<script>...your code...</script>
3. External File (Best Practice):
<script src="app.js"></script>
💡 Best Practice: Put scripts at the end of <body> so HTML loads first!
<!DOCTYPE html>
<html>
<head>
<title>My Page</title>
</head>
<body>
<h1>Hello World</h1>
<button id="myBtn">Click Me</button>
<!-- JavaScript at the end -->
<script>
console.log('Page loaded!');
document.getElementById('myBtn')
.addEventListener('click', () => {
alert('Button clicked!');
});
</script>
</body>
</html>
Declaring Variables:
const - Cannot be reassigned (use by default)let - Can be reassignedvar - Old way (avoid using)Data Types:
42, 3.14'text', "text"true, false[1, 2, 3]{name: 'John', age: 25}// Numbers
const temperature = 25.5;
const count = 100;
// Strings
const name = 'Arduino';
const sensor = "DHT11";
// Booleans
const isConnected = true;
const hasError = false;
// Arrays
const temps = [25.5, 26.0, 25.8];
const sensors = ['DHT11', 'MF52A'];
// Objects
const reading = {
temperature: 25.5,
humidity: 60,
timestamp: '10:30:00'
};
The Console is Your Best Friend!
Press F12 in your browser to open Developer Tools, then go to the Console tab.
Console Methods:
console.log() - Print messagesconsole.error() - Print errorsconsole.warn() - Print warningsconsole.table() - Display arrays/objects nicely💡 Debugging Tip: Use console.log() everywhere to see what your code is doing!
// Basic logging
console.log('Hello World');
// Multiple values
const temp = 25.5;
console.log('Temperature:', temp);
// Objects
const sensor = {dht: 25.5, mf52: 25.3};
console.log('Sensor data:', sensor);
console.table(sensor); // Nice table format!
// Arrays
const readings = [25, 26, 24];
console.log('Readings:', readings);
// Errors
console.error('Connection failed!');
// Check variable types
console.log(typeof temp); // "number"
console.log(typeof sensor); // "object"
Functions are reusable blocks of code.
Three Ways to Define Functions:
function name() {...}const name = function() {...}const name = () => {...}💡 Tip: Arrow functions are shorter and commonly used in modern JavaScript!
// Function Declaration
function greet(name) {
return 'Hello ' + name;
}
// Function Expression
const calculateAverage = function(numbers) {
const sum = numbers.reduce((a, b) => a + b, 0);
return sum / numbers.length;
};
// Arrow Function (Recommended)
const celsiusToFahrenheit = (celsius) => {
return celsius * 9/5 + 32;
};
// Short arrow function (one line)
const square = (x) => x * x;
// Using functions
console.log(greet('John'));
console.log(calculateAverage([25, 26, 24]));
console.log(celsiusToFahrenheit(25));
DOM = Document Object Model - JavaScript's way to interact with HTML.
Selecting Elements:
getElementById() - Select by IDquerySelector() - Select by CSS selectorquerySelectorAll() - Select all matching elements💡 Tip: Use querySelector - it's flexible and works like CSS!
// HTML: <div id="temp">25°C</div>
const tempDiv = document.getElementById('temp');
// Using querySelector (more flexible)
const tempDiv2 = document.querySelector('#temp');
const div = document.querySelector('div');
const button = document.querySelector('button');
// Select multiple elements
const alldivs = document.querySelectorAll('div');
console.log('Found', alldivs.length, 'divs');
// Loop through elements
alldivs.forEach((div) => {
console.log(div);
});
// Check if element exists
if (tempDiv) {
console.log('Element found!');
} else {
console.log('Element not found!');
}
Common Properties:
textContent - Text only (safe)innerHTML - HTML content (use carefully)value - For input fieldsstyle - Inline CSS styles💡 Security Tip: Use textContent unless you specifically need HTML!
// Update text
const tempDisplay = document.getElementById('temp');
tempDisplay.textContent = '26.5°C';
// Update with HTML
const status = document.getElementById('status');
status.innerHTML = '<strong>Connected</strong>';
// Get/Set input values
const nameInput = document.getElementById('nameInput');
console.log(nameInput.value); // Get value
nameInput.value = 'John'; // Set value
// Update styles
tempDisplay.style.color = 'red';
tempDisplay.style.fontSize = '24px';
tempDisplay.style.fontWeight = 'bold';
// Add/remove CSS classes
tempDisplay.classList.add('highlight');
tempDisplay.classList.remove('hidden');
tempDisplay.classList.toggle('active');
Common Events:
'click' - Mouse click'input' - Text input changed'change' - Value changed'submit' - Form submitted'keypress' - Key pressed'load' - Page/image loaded💡 Tip: Always use addEventListener instead of inline onclick!
// Click event
const button = document.getElementById('myBtn');
button.addEventListener('click', () => {
console.log('Button clicked!');
});
// With event object
button.addEventListener('click', (event) => {
console.log('Clicked element:', event.target);
});
// Input event (fires as user types)
const searchBox = document.getElementById('search');
searchBox.addEventListener('input', (e) => {
console.log('Current value:', e.target.value);
});
// Multiple event listeners
const refreshBtn = document.getElementById('refresh');
refreshBtn.addEventListener('click', fetchData);
refreshBtn.addEventListener('click', updateUI);
// Remove event listener
const handler = () => console.log('Clicked');
button.addEventListener('click', handler);
button.removeEventListener('click', handler);
Arrays store multiple values in a single variable.
Common Array Methods:
push() - Add to endpop() - Remove from endshift() - Remove from startunshift() - Add to startforEach() - Loop through itemsmap() - Transform itemsfilter() - Filter items// Create array
const temps = [25.5, 26.0, 25.8, 26.2];
// Add/remove items
temps.push(26.5); // Add to end: [25.5, 26.0, 25.8, 26.2, 26.5]
temps.pop(); // Remove from end: [25.5, 26.0, 25.8, 26.2]
temps.shift(); // Remove from start: [26.0, 25.8, 26.2]
temps.unshift(25.5); // Add to start: [25.5, 26.0, 25.8, 26.2]
// Loop through array
temps.forEach((temp) => {
console.log(temp + '°C');
});
// Transform array (convert to Fahrenheit)
const fahrenheit = temps.map((c) => c * 9/5 + 32);
// Filter array (only temps above 26)
const hot = temps.filter((temp) => temp > 26);
// Get array length
console.log('Total readings:', temps.length);
Objects store related data as key-value pairs.
Accessing Object Properties:
object.propertyobject['property']💡 Use Case: Perfect for sensor data with multiple fields!
// Create object
const sensorData = {
dht: 25.5,
mf52: 25.3,
humidity: 60,
timestamp: '10:30:00'
};
// Access properties
console.log(sensorData.dht); // 25.5
console.log(sensorData['mf52']); // 25.3
// Add new property
sensorData.outdoor = 22.0;
// Update property
sensorData.dht = 26.0;
// Delete property
delete sensorData.humidity;
// Check if property exists
if ('dht' in sensorData) {
console.log('DHT exists');
}
// Loop through properties
for (const key in sensorData) {
console.log(key + ':', sensorData[key]);
}
JSON is a text format for storing and exchanging data.
Why JSON?
Key Methods:
JSON.parse() - Convert JSON string to objectJSON.stringify() - Convert object to JSON string💡 Your Project: Arduino sends JSON, JavaScript parses it!
// JavaScript object
const data = {
dht: 25.5,
mf52: 25.3,
timestamp: '10:30:00'
};
// Convert to JSON string
const jsonString = JSON.stringify(data);
console.log(jsonString);
// Output: {"dht":25.5,"mf52":25.3,"timestamp":"10:30:00"}
// Parse JSON string to object
const jsonFromServer = '{"dht":26.0,"mf52":25.8}';
const parsed = JSON.parse(jsonFromServer);
console.log(parsed.dht); // 26.0
// Example: Parsing Arduino data
const arduinoData = '{"dht":25.5,"mf52":25.3}';
const sensor = JSON.parse(arduinoData);
document.getElementById('temp').textContent =
sensor.dht + '°C';
If-Else Statements:
Execute code based on conditions.
Comparison Operators:
=== Equal to (strict)!== Not equal to> Greater than< Less than>= Greater or equal<= Less or equal💡 Tip: Use === not == for safer comparisons!
const temperature = 28;
// Simple if
if (temperature > 30) {
console.log('Hot!');
}
// If-else
if (temperature > 30) {
console.log('Hot!');
} else {
console.log('Comfortable');
}
// If-else-if
if (temperature > 30) {
console.log('Hot!');
} else if (temperature > 20) {
console.log('Warm');
} else {
console.log('Cold');
}
// Logical operators
if (temperature > 25 && temperature < 30) {
console.log('Perfect!');
}
if (temperature < 10 || temperature > 35) {
console.log('Extreme temperature!');
}
Two Main Functions:
setTimeout() - Execute once after delaysetInterval() - Execute repeatedly at intervalsTime is in milliseconds:
💡 Tip: Always clear intervals when done to prevent memory leaks!
// Execute once after 3 seconds
setTimeout(() => {
console.log('3 seconds passed!');
}, 3000);
// Execute every 2 seconds
const intervalId = setInterval(() => {
console.log('This runs every 2 seconds');
}, 2000);
// Stop the interval after 10 seconds
setTimeout(() => {
clearInterval(intervalId);
console.log('Interval stopped');
}, 10000);
// Example: Update clock every second
function updateClock() {
const now = new Date();
document.getElementById('clock').textContent =
now.toLocaleTimeString();
}
setInterval(updateClock, 1000);
// Clear timeout
const timeoutId = setTimeout(() => {}, 5000);
clearTimeout(timeoutId);
Template literals use backticks (``) and allow:
${}💡 Much Cleaner: No more messy string concatenation with +!
const temperature = 25.5;
const sensor = 'DHT11';
// Old way (hard to read)
const message1 = 'Temperature from ' + sensor + ' is ' + temperature + '°C';
// New way (clean and readable)
const message2 = `Temperature from ${sensor} is ${temperature}°C`;
// With expressions
const fahrenheit = temperature * 9/5 + 32;
const message3 = `${temperature}°C = ${fahrenheit}°F`;
// Multi-line strings
const report = `
Sensor Report:
- DHT11: ${temperature}°C
- Status: Connected
- Time: ${new Date().toLocaleTimeString()}
`;
console.log(report);
// In DOM manipulation
document.getElementById('status').innerHTML = `
<strong>${sensor}</strong>: ${temperature}°C
`;
You'll Use These Frequently:
💡 Key Skills: DOM manipulation, arrays, objects, and event handling!
// Pattern 1: Update display from sensor data
function updateDisplay(data) {
document.getElementById('dhtTemp').textContent =
`${data.dht.toFixed(1)}°C`;
document.getElementById('mf52Temp').textContent =
`${data.mf52.toFixed(1)}°C`;
}
// Pattern 2: Keep array at fixed size
const readings = [];
const MAX_SIZE = 50;
function addReading(value) {
readings.push(value);
if (readings.length > MAX_SIZE) {
readings.shift(); // Remove oldest
}
}
// Pattern 3: Calculate statistics
function calculateAverage(arr) {
if (arr.length === 0) return 0;
const sum = arr.reduce((a, b) => a + b, 0);
return (sum / arr.length).toFixed(1);
}
Common Errors and Solutions:
1. "Cannot read property of undefined"
if (obj) { ... }2. "element is null"
3. Nothing happens
💡 Always: Open DevTools (F12) and check Console tab!
✅ Do:
const by default, let when neededtemperature not t=== instead of == for comparisons<body>❌ Don't:
var (use const or let)onclickdata, temp, xBuild a simple temperature converter!
Requirements:
F = C × 9/5 + 32💡 Bonus: Make it convert automatically as the user types (use 'input' event)!
Skills Used: DOM selection, event listeners, functions, conditionals, template literals
Useful Features You'll See:
1. Destructuring: Extract values easily
2. Spread Operator: Copy/combine arrays
3. Default Parameters: Set defaults
💡 These make code cleaner and more readable!
// 1. Destructuring
const sensor = {dht: 25.5, mf52: 25.3};
const {dht, mf52} = sensor;
console.log(dht); // 25.5
// Array destructuring
const temps = [25, 26, 24];
const [first, second] = temps;
console.log(first); // 25
// 2. Spread operator
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = [...arr1, ...arr2];
// [1, 2, 3, 4, 5, 6]
// Copy array
const copy = [...temps];
// 3. Default parameters
function greet(name = 'Guest') {
return `Hello ${name}`;
}
console.log(greet()); // "Hello Guest"
Chart.js is a JavaScript library for creating charts.
Basic Steps:
<canvas> element💡 Your Project: You'll create 3 line charts for temperature data!
<!-- Include Chart.js -->
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.js"></script>
<!-- Canvas element -->
<canvas id="tempChart"></canvas>
<script>
// Create chart
const ctx = document.getElementById('tempChart').getContext('2d');
const chart = new Chart(ctx, {
type: 'line',
data: {
labels: ['10:00', '10:01', '10:02'],
datasets: [{
label: 'Temperature',
data: [25, 26, 25.5],
borderColor: 'rgb(75, 192, 192)'
}]
}
});
// Update chart with new data
chart.data.labels.push('10:03');
chart.data.datasets[0].data.push(26.2);
chart.update();
</script>
Real-Time Chart Animation:
This example demonstrates continuous chart updates by plotting a moving sine wave.
Key Concepts:
💡 This Pattern: Same approach used for real-time sensor data!
<canvas id="sineChart"></canvas>
<script>
const ctx = document.getElementById('sineChart').getContext('2d');
const chart = new Chart(ctx, {
type: 'line',
data: {
labels: [],
datasets: [{
label: 'sin(x)',
data: [],
borderColor: 'rgb(75, 192, 192)',
tension: 0.4
}]
}
});
let x = 0;
const MAX_POINTS = 50;
setInterval(() => {
const y = Math.sin(x);
chart.data.labels.push(x.toFixed(2));
chart.data.datasets[0].data.push(y);
if (chart.data.labels.length > MAX_POINTS) {
chart.data.labels.shift();
chart.data.datasets[0].data.shift();
}
chart.update('none');
x += 0.1;
}, 100);
</script>
The Date Object:
Used for timestamps, scheduling, and time-based features.
Common Methods:
new Date() - Current date/timetoLocaleTimeString() - Format timetoLocaleDateString() - Format dategetTime() - Milliseconds since 1970💡 Use Case: Adding timestamps to sensor readings!
// Current date and time
const now = new Date();
console.log(now);
// Format time
const time = now.toLocaleTimeString();
console.log(time); // "10:30:45 AM"
// Format date
const date = now.toLocaleDateString();
console.log(date); // "10/29/2025"
// Get individual components
console.log(now.getHours()); // 10
console.log(now.getMinutes()); // 30
console.log(now.getSeconds()); // 45
// Create custom timestamp
const timestamp = `${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`;
// Calculate time difference
const start = new Date();
// ... some operations ...
const end = new Date();
const elapsed = end - start; // milliseconds
console.log(`Took ${elapsed}ms`);
Handle errors gracefully to prevent crashes.
Why Use Try-Catch?
💡 Best Practice: Always wrap risky operations (parsing JSON, API calls) in try-catch!
// Basic try-catch
try {
const data = JSON.parse(jsonString);
console.log(data);
} catch (error) {
console.error('Failed to parse:', error);
}
// With user feedback
function updateSensorDisplay(jsonData) {
try {
const data = JSON.parse(jsonData);
document.getElementById('temp').textContent =
data.temperature + '°C';
} catch (error) {
console.error('Error:', error);
document.getElementById('temp').textContent =
'Error reading sensor';
}
}
// With finally (always executes)
try {
fetchData();
} catch (error) {
console.error('Error:', error);
} finally {
console.log('Cleanup complete');
}
Local Storage allows saving data in the browser.
Key Methods:
localStorage.setItem(key, value) - SavelocalStorage.getItem(key) - RetrievelocalStorage.removeItem(key) - DeletelocalStorage.clear() - Clear all⚠️ Important: Can only store strings, use JSON.stringify/parse for objects!
💡 Use Case: Remember user settings, save data between sessions
// Save string
localStorage.setItem('username', 'John');
// Retrieve string
const username = localStorage.getItem('username');
console.log(username); // "John"
// Save object (must stringify)
const settings = {
theme: 'dark',
notifications: true
};
localStorage.setItem('settings', JSON.stringify(settings));
// Retrieve object (must parse)
const savedSettings = localStorage.getItem('settings');
const parsed = JSON.parse(savedSettings);
console.log(parsed.theme); // "dark"
// Delete item
localStorage.removeItem('username');
// Clear all
localStorage.clear();
// Check if key exists
if (localStorage.getItem('username')) {
console.log('Username found');
}
These patterns appear everywhere in web development:
💡 Master These: They're the foundation of interactive web apps!
// Pattern 1: Safe element access
const element = document.getElementById('temp');
if (element) {
element.textContent = '25°C';
}
// Pattern 2: Validate before processing
function processData(data) {
if (!data || typeof data.temperature !== 'number') {
console.error('Invalid data');
return;
}
// Process valid data
}
// Pattern 3: Array with max size (sliding window)
function addWithLimit(array, value, maxSize) {
array.push(value);
if (array.length > maxSize) {
array.shift();
}
}
// Pattern 4: Format numbers
const temp = 25.567;
console.log(temp.toFixed(1)); // "25.6"
console.log(temp.toFixed(2)); // "25.57"
Official Documentation:
Interactive Learning:
Practice:
💡 Best Way to Learn: Code every day, even for 15 minutes!