Day 99 of me reading random and basic but important dev topicsss.... Today I read about the Scaling Cancellations in JavaScript..... Yesterday, I read how to cancel a single fetch() request using AbortController to prevent memory leaks and UI bugs. But what if we're building a complex dashboard loading dozens of widgets simultaneously? Good news is AbortController is highly scalable.... You don’t need to instantiate a new controller for every single request. A single AbortController signal can be passed to multiple fetch calls. If the user hits "Cancel" or navigates away, calling controller.abort() once will instantly kill all associated network requests! const controller = new AbortController(); const urls = ['/api/users', '/api/analytics', '/api/settings']; // Map URLs to fetch promises, all sharing the same exact signal const fetchJobs = urls.map(url => fetch(url, { signal: controller.signal }) ); try { const results = await Promise.all(fetchJobs); console.log("All data loaded successfully!"); } catch (err) { if (err.name === 'AbortError') { console.log(" ALL parallel requests were aborted instantly!"); } } // Call this from anywhere in your app to cancel everything: // controller.abort(); Note: It's not just for fetch...... You don't have to limit yourself to network requests. AbortController is an elegant, universal event bus for cancellation. You can integrate it into your own custom asynchronous tasks. Since controller.signal emits a standard event, all you need to do is listen for the 'abort' event within your custom Promise: const ourCustomJob = new Promise((resolve, reject) => { // ... Heavy background task logic here ... // Tie your custom task to the same controller controller.signal.addEventListener('abort', () => { reject(new Error("Custom Job Aborted!")); }); }); // Now Promise.all([ ...fetchJobs, ourCustomJob ]) can ALL be managed together! By standardizing cancellation across your app using AbortController, you ensure clean garbage collection, eliminate race conditions, and drastically save your users' network bandwidth. Keep Learning!!!! #JavaScript #AsyncProgramming #WebDev #SoftwareEngineering #CleanCodee
Sankalp Mishra’s Post
More Relevant Posts
-
🚀 Fetch vs Axios in JavaScript When building modern web applications, interacting with APIs is a daily task. Two of the most commonly used tools for this are Fetch and Axios. 🔹 What is fetch()? Definition: fetch() is a built-in Web API in JavaScript used to make HTTP requests to servers and retrieve resources. 👉 It is promise-based and available in all modern browsers. 📌 How Fetch Works >> Sends a request to a server (GET, POST, etc.) >> Returns a Promise >> Resolves to a Response object >> You must extract data manually (e.g., .json()) 💻 Example async function fetchData() { try { const response = await fetch("https://lnkd.in/dQeGAVaB"); // Checking response status manually if (!response.ok) { throw new Error("HTTP error! Status: " + response.status); } // Convert response into JSON const data = await response.json(); console.log(data); } catch (error) { console.error("Fetch Error:", error); } } ⚠️ Important Characteristics of Fetch ✔️ Built into browser (no installation) ✔️ Returns Promise ✔️ Requires manual JSON parsing ✔️ Does NOT throw errors for HTTP failures (you must handle it) ✔️ Slightly more verbose 🔹 What is axios? Definition: axios is a third-party JavaScript library used to make HTTP requests from the browser or Node.js. 👉 It is also promise-based but provides many additional features out of the box. 📌 How Axios Works >> Sends HTTP requests (GET, POST, PUT, DELETE, etc.) >> Automatically transforms response into JSON >> Automatically throws errors for bad status codes >> Provides advanced configuration options 💻 Example import axios from "axios"; async function fetchData() { try { const response = await axios.get("https://lnkd.in/dQeGAVaB"); // Axios directly gives data console.log(response.data); } catch (error) { console.error("Axios Error:", error); } } ⚠️ Important Characteristics of Axios ✔️ Requires installation (npm install axios) ✔️ Automatic JSON transformation ✔️ Better error handling ✔️ Supports interceptors (modify request/response globally) ✔️ Supports timeout, cancellation, headers easily ✔️ Cleaner and shorter syntax 💡 When to Use Fetch vs Axios? 👉 Use Fetch when: >> You want a lightweight solution >> No external dependencies required >> Working on small/simple projects 👉 Use Axios when: >> You are building real-world applications >> Need better error handling >> Want features like: >>Interceptors, Global configuration, Request cancellation #JavaScript #WebDevelopment #Axios #FetchAPI #Frontend #Programming #Developers #Coding
To view or add a comment, sign in
-
🚀 30 Days of JavaScript – Day 20 Today I upgraded my To-Do App with more advanced features. 💡 Project: Advanced To-Do App New features added: • Mark tasks as completed • Edit existing tasks • Delete tasks • Store data using localStorage 🧠 Concepts Used: • DOM manipulation • CRUD operations • local Storage • dynamic UI updates 📌 This project helped me understand how real applications manage and update data. 🎥 Demo below 👇 👉 Source code in (only JS Code). #JavaScript #FrontendDevelopment #WebDevelopment #LearningJavaScript #CodingJourney <script> let tasks = JSON.parse(localStorage.getItem("tasks")) || []; function showTasks() { let list = document.getElementById("taskList"); list.innerHTML = ""; tasks.forEach((task, index) => { let li = document.createElement("li"); let text = document.createElement("span"); text.innerText = task.name; if (task.completed) { text.classList.add("completed"); } // actions let actions = document.createElement("div"); actions.className = "actions"; // complete button let completeBtn = document.createElement("button"); completeBtn.innerText = "✔"; completeBtn.onclick = function() { toggleComplete(index); }; // edit button let editBtn = document.createElement("button"); editBtn.innerText = "Edit"; editBtn.onclick = function() { editTask(index); }; // delete button let deleteBtn = document.createElement("button"); deleteBtn.innerText = "X"; deleteBtn.onclick = function() { deleteTask(index); }; actions.appendChild(completeBtn); actions.appendChild(editBtn); actions.appendChild(deleteBtn); li.appendChild(text); li.appendChild(actions); list.appendChild(li); }); } function addTask() { let input = document.getElementById("taskInput"); if (input.value === "") { alert("Enter task"); return; } tasks.push({ name: input.value, completed: false }); localStorage.setItem("tasks", JSON.stringify(tasks)); input.value = ""; showTasks(); } function deleteTask(index) { tasks.splice(index, 1); localStorage.setItem("tasks", JSON.stringify(tasks)); showTasks(); } function toggleComplete(index) { tasks[index].completed = !tasks[index].completed; localStorage.setItem("tasks", JSON.stringify(tasks)); showTasks(); } function editTask(index) { let newTask = prompt("Edit your task:", tasks[index].name); if (newTask !== null && newTask !== "") { tasks[index].name = newTask; localStorage.setItem("tasks", JSON.stringify(tasks)); showTasks(); } } showTasks(); </script>
To view or add a comment, sign in
-
🚀 Day 24 – Functions & Advanced Concepts in JavaScript Today’s focus is not just theory — it’s how these concepts are used in REAL applications 👇 🔹 1. Debounce 👉 Executes function only after user stops triggering it for a delay. function debounce(fn, delay) { let timer; return function (...args) { clearTimeout(timer); timer = setTimeout(() => { fn.apply(this, args); }, delay); }; } Real-time scenario: In an e-commerce website, when a user searches for a product, we don’t call API on every keystroke. Instead, we wait until the user stops typing → then trigger API. 👉 Prevents 20+ unnecessary API calls! 🔹 2. Throttle 👉 Ensures function runs only once in a given interval. function throttle(fn, limit) { let flag = true; return function (...args) { if (!flag) return; flag = false; fn.apply(this, args); setTimeout(() => { flag = true; }, limit); }; } Real-time scenario: While scrolling Instagram/LinkedIn feed, scroll events fire continuously. Throttle ensures smooth performance by limiting executions. 👉 Prevents UI lag & improves performance 🔹 3. Currying 👉 Converts multiple arguments into nested functions. function curry(a) { return function (b) { return function (c) { return a + b + c; }; }; } console.log(curry(2)(3)(4)); // 9 Real-time scenario: In large apps, we create reusable utility functions. Example: Tax calculator → instead of passing all values every time, we reuse partial functions. 👉 Helps in clean & reusable code 🔹 4. Memoization 👉 Caches results to avoid recalculating. function memoize(fn) { const cache = {}; return function (n) { if (cache[n]) return cache[n]; const result = fn(n); cache[n] = result; return result; }; } Real-time scenario: In dashboards (finance/analytics apps), heavy calculations run repeatedly. Memoization stores results → avoids recomputation. 🔹 5. Closures ⭐ 👉 A function remembers variables from its outer scope even after execution. function outer() { let count = 0; return function inner() { count++; return count; }; } const counter = outer(); console.log(counter()); // 1 console.log(counter()); // 2 Real-time scenario: ✔ Data hiding ✔ Maintaining state (like counters, caches) Used in: ✔ Counters (cart items count) ✔ Private variables (data hiding) ✔ setTimeout inside loops 👉 Helps maintain state without global variables 🔹 6. Pure Functions 👉 Function that always returns same output for same input and has no side effects. function add(a, b) { return a + b; } Real-time scenario: In state management (Angular/React), pure functions ensure predictable updates. Why important? ✔ Predictable ✔ Easy to test ✔ Used in frameworks like Angular & React 👉 Easier debugging & testing #JavaScript #FrontendDeveloper #Angular #InterviewPrep #Coding #WebDevelopment
To view or add a comment, sign in
-
The app was fast on day one. By day thirty - it was crawling. There was no major code change. No new features had been added. But something was quietly accumulating in the background. Somehow it kept growing and consuming more. That something was a memory leak. And it had been there from the beginning. How JavaScript manages memory: JavaScript handles memory automatically. If you create an object(s), JavaScript allocates memory. When those objects are no longer needed - JavaScript cleans them up. This cleanup process is called Garbage Collection. It works using a mark-and-sweep algorithm. Mark - JavaScript starts from the root of your application and traces every object that is still reachable and in use. It marks them all as active. Sweep - Everything that wasn't marked is considered inactive. Objects with no path back to the root, is considered unreachable. JavaScript reclaims that memory and frees it up. This process happens automatically. However, there cases where your code accidentally keeps holding on to things it should have let go - memory leak. What causes memory leaks in Single Page Apps? In a Single Page App, the page never fully refreshes. Components come and go. Data loads and updates. And if references to old, unused objects are never properly cleared, the garbage collector can never touch them. They sit in memory quietly growing until the app slows to a crawl. Here are the four most common culprits: -> Event Listeners Adding a listener when component mounts. If never removed when component unmounts - it stays forever // Fix: Always remove your listener after it mounts. -> Closures - remembering too much. In closures, functions and variables always remember their environment of creation. A closure keeps a reference to its variables so they stay alive in memory regardless. The garbage collector cannot touch them. -> Forgotten Timers - setInterval, clearInerval. Timers still run even after their purpose is long gone. If not cleared, the entire callback environment stays alive and holds references to variables and objects that should have been freed long ago. How to catch memory leaks. Think of your app's memory like a bucket of water. Every time your app creates objects, adds listeners, or stores data - water goes into the bucket. Every time the garbage collector cleans up - water leaves the bucket. A healthy app - the water level rises and falls naturally. A leaking app - the water level keeps rising. And rising. And never comes back down. Chrome DevTools shows you the bucket. Here's how: Open your browser and press F12 to open DevTools Click the "Memory" tab at the top Click "Take Snapshot" - this is a photograph of everything currently sitting in your memory Use your app normally - click buttons, navigate pages, load data Take another snapshot Compare the two If the second snapshot shows significantly more memory than the first, and that memory never drops, there's a memory leak.
To view or add a comment, sign in
-
❓ What actually happens when you call fetch('/api')? So I sat down and figured it out. Here's what blew my mind 👇 💡 The JS engine itself is TINY. Just two things inside it: 📦 Memory Heap — where your objects live 📚 Call Stack — tracks what function is running That's it. It can't do timers. It can't make network requests. It can't even listen for a click. 🤯 🎭 So who does all the async work? The BROWSER does. Not JavaScript. ⚙️ Web APIs (written in C++) handle the heavy lifting on separate threads: 🌐 fetch — network requests ⏱️ setTimeout — timers 🖥️ DOM — page manipulation 🖱️ Events — clicks, scrolls, keypresses 💾 LocalStorage, Geolocation, WebSockets… When they finish, they drop callbacks into two queues: 🟢 Microtask Queue (HIGH priority) → Promises, await, queueMicrotask 🔴 Callback Queue (LOW priority) → setTimeout, click, fetch response 🔄 Then the Event Loop steps in: 1️⃣ Is the Call Stack empty? 2️⃣ Drain ALL microtasks first 3️⃣ Run ONE macrotask 4️⃣ Let the browser paint 5️⃣ Repeat forever 🎯 This explains SO much: ✅ Why a heavy loop freezes your page (stack never empties) ✅ Why Promise.then() ALWAYS beats setTimeout(fn, 0) ✅ Why async/await isn't magic — it's just microtask syntax ✅ Why single-threaded doesn't mean single-tasking 👨🍳 My favorite mental model: The JS engine is a single chef. Web APIs are robot assistants running errands in the background. The Microtask Queue is the VIP line. The Callback Queue is the regular line. The Event Loop is the maître d' — but only seats people when the chef is free. 💥 The biggest realization: "JavaScript" the language and "JavaScript" the thing running in your browser are two VERY different things. ✨ The language is small. 🌊 The runtime around it is massive. I mapped the whole thing out with diagrams — call stack traces, V8's Ignition/TurboFan pipeline, the full click-to-fetch-to-DOM lifecycle. Dropping it in the comments 👇 👋 What's something you use every day but never really looked under the hood of? #JavaScript #WebDevelopment #Frontend #V8 #EventLoop #CodeNewbie
To view or add a comment, sign in
-
𝗝𝗮𝘃𝗮𝗦𝗰𝗿𝗶𝗽𝘁 𝗶𝘀 𝘀𝗶𝗻𝗴𝗹𝗲-𝘁𝗵𝗿𝗲𝗮𝗱𝗲𝗱. So how does your UI stay responsive while a fetch() is running? Most devs say "async/await". That's not an answer. That's a keyword. Here's what actually happens. 👇 ━━━━━━━━━━━━━━━━━━━━━━━ 𝗧𝗿𝗮𝗰𝗲 𝗮 𝘀𝗶𝗻𝗴𝗹𝗲 𝗳𝗲𝘁𝗰𝗵() 𝗰𝗮𝗹𝗹 𝘁𝗵𝗿𝗼𝘂𝗴𝗵 𝘁𝗵𝗲 𝗲𝗻𝘁𝗶𝗿𝗲 𝗲𝗻𝗴𝗶𝗻𝗲: 𝗦𝘁𝗲𝗽 𝟭 — fetch() hits the Call Stack. The JS engine sees it, pushes it on the stack. But fetch() is not pure JS — it's a Web API. 𝗦𝘁𝗲𝗽 𝟮 — The Call Stack offloads it to the Web API layer. The network request leaves JavaScript entirely. Your browser (or Node.js libuv) handles it in a separate thread. The Call Stack is now FREE. UI stays responsive. 𝗦𝘁𝗲𝗽 𝟯 — Response arrives. Callback enters the Task Queue. The Web API layer puts your .then() or await callback into the appropriate queue and waits. 𝗦𝘁𝗲𝗽 𝟰 — The Event Loop checks both queues. Microtask Queue first (Promise.then, MutationObserver). Drain it completely. Then take ONE callback from the Task Queue. 𝗦𝘁𝗲𝗽 𝟱 — Callback pushed onto the Call Stack. Executed. Your data is now in your component. ━━━━━━━━━━━━━━━━━━━━━━━ 𝗧𝗵𝗲 𝗽𝗮𝗿𝘁 𝗺𝗼𝘀𝘁 𝗱𝗲𝘃𝘀 𝗺𝗶𝘀𝘀: "Non-blocking" doesn't mean JavaScript runs in parallel. It means the blocking work is delegated to something that CAN run in parallel — Web APIs, OS threads, libuv. JavaScript itself never leaves the single thread. The illusion of concurrency comes from the queue system. ━━━━━━━━━━━━━━━━━━━━━━━ 𝗧𝗵𝗶𝘀 𝗶𝘀 𝘄𝗵𝘆: → A long synchronous loop BLOCKS your UI (it holds the Call Stack and the Event Loop never runs) → An awaited fetch() does NOT block your UI (it's off the Call Stack within microseconds) → CPU-heavy work should go in a Web Worker (move it off the main thread entirely) ━━━━━━━━━━━━━━━━━━━━━━━ The whiteboard above shows the full flow visually. Save it + this explanation as a pair. 📌 Interview question: "Is JavaScript asynchronous?" Correct answer: No — it's single-threaded and synchronous. Async behavior comes from the runtime environment around it. Drop a 🔥 if this clicked for you today. #JavaScript #FrontendDevelopment #ReactJS #NodeJS #SoftwareEngineering #OpenToWork #ImmediateJoiner
To view or add a comment, sign in
-
-
"Which analytics SDK works with React, Vue, Node.js, and plain JavaScript?" All of them, if you count the setup time in days. SensorCore — AI-native analytics via MCP — has a universal JS SDK that works everywhere JavaScript runs. Setup takes 60 seconds. Install: npm install sensorcore Configure: import SensorCore from 'sensorcore'; SensorCore.configure({ apiKey: 'sc_YOUR_API_KEY' }); Log events: SensorCore.log('Checkout Started', { metadata: { plan: 'pro', source: 'pricing_page', platform: 'web' } }); That's three steps. You're done. Works everywhere: - React — call SensorCore.log() in event handlers or useEffect - Vue — call it in methods or lifecycle hooks - Node.js — log from your Express/Fastify/Next.js backend - Plain JS — works in any browser environment Same API. Same apiKey. Same data pipeline. Your AI agent sees events from all platforms in one unified stream. What happens after you log: SensorCore.log() → POST /api/logs → ClickHouse ↓ AI agent queries via MCP ↓ "Users from pricing_page convert 3x more" One SDK, all platforms, AI-powered analysis. No separate dashboard to check. What's your current analytics stack? Is it the same SDK across frontend and backend?
To view or add a comment, sign in
-
🧠 Why React.memo Sometimes Doesn’t Work You wrap your component: const Child = React.memo(({ data }) => { console.log("Rendered"); return <div>{data}</div>; }); You expect it to not re-render. But it still does. Why? 🔍 The real reason React.memo does shallow comparison. So if you pass this 👇 <Child data={{ value: count }} /> 👉 That object is new on every render Even if count didn’t change. ⚠️ Result React sees: {} !== {} 👉 “Props changed” → re-render happens ✅ Fix Memoize the object: const memoData = useMemo(() => { return { value: count }; }, [count]); <Child data={memoData} /> Now the reference stays stable. 🎯 Real Insight React.memo doesn’t prevent re-renders. It only skips them when props are the same reference. 💥 Senior takeaway Most “optimization” fails because of unstable references, not logic. 🧠 Why React.memo Sometimes Doesn’t Work You wrap your component: const Child = React.memo(({ data }) => { console.log("Rendered"); return <div>{data}</div>; }); You expect it to not re-render. But it still does. Why? 🔍 The real reason React.memo does shallow comparison. So if you pass this 👇 <Child data={{ value: count }} /> 👉 That object is new on every render Even if count didn’t change. ⚠️ Result React sees: {} !== {} 👉 “Props changed” → re-render happens ✅ Fix Memoize the object: const memoData = useMemo(() => { return { value: count }; }, [count]); <Child data={memoData} /> Now the reference stays stable. 🎯 Real Insight React.memo doesn’t prevent re-renders. It only skips them when props are the same reference. 💥 Senior takeaway Most “optimization” fails because of unstable references, not logic. #ReactJS #FrontendDeveloper #JavaScript #WebPerformance #SoftwareEngineering #CodingTips #TechCareers #LearningInPublic
To view or add a comment, sign in
-
🚀 React Hooks: The Game-Changer Every Developer Must Master If you're working with React and still relying heavily on class components… it's time to level up. React Hooks completely transformed how we build components — making code cleaner, reusable, and easier to manage. Let’s break it down in a way that actually makes sense 👇 🔥 What are React Hooks? Hooks are special functions introduced in React 16.8 that allow you to use state and lifecycle features in functional components. 👉 No more bulky classes 👉 No more confusing this keyword 👉 Just clean, readable functions 🧠 Why Hooks Matter? ✔ Simplifies component logic ✔ Promotes code reuse ✔ Improves readability ✔ Makes testing easier ✔ Reduces boilerplate code ⚡ Most Important Hooks You Should Know 1. 🟢 useState Manages state inside functional components. JavaScript const [count, setCount] = useState(0); 👉 Perfect for counters, forms, toggles 2. 🔵 useEffect Handles side effects like API calls, subscriptions, DOM updates. JavaScript useEffect(() => { console.log("Component mounted"); }, []); 👉 Think of it as componentDidMount + componentDidUpdate + componentWillUnmount 3. 🟣 useContext Avoids prop drilling by sharing data globally. 👉 Great for themes, auth, user data 4. 🟡 useRef Access DOM elements or persist values without re-render. JavaScript const inputRef = useRef(); 5. 🔴 useMemo & useCallback Optimize performance by memoizing values and functions. 👉 Prevent unnecessary re-renders 👉 Crucial for large-scale apps 💡 Pro Tips (From Real Projects) ✅ Don’t overuse useEffect — keep dependencies clean ✅ Use useMemo only when performance actually matters ✅ Break complex logic into custom hooks ✅ Follow naming convention: useSomething() 🚀 Custom Hooks = Real Power You can create your own hooks to reuse logic: JavaScript function useFetch(url) { // reusable logic } 👉 This is where senior-level React starts 💯 ⚠️ Common Mistakes to Avoid ❌ Calling hooks inside loops/conditions ❌ Ignoring dependency array in useEffect ❌ Over-optimizing with memoization ❌ Mixing too much logic in one component 🏁 Final Thought React Hooks are not just a feature — they are a mindset shift. If you truly master hooks, you move from writing code ➝ to designing scalable front-end systems. 💬 Want React + .NET Interview Questions & Real Project Scenarios? Comment "HOOKS" and I’ll share 🚀 🔖 #ReactJS #FrontendDevelopment #JavaScript #WebDevelopment #ReactHooks #Coding #SoftwareDevelopment #TechLearning #Developers #100DaysOfCode #Programming #ReactDeveloper #AngularVsReact #DotNet #FullStackDeveloper
To view or add a comment, sign in
-
-
Day 12 of 90: Migrating a Live AI App Frontend from HTML to React Today I rebuilt my AI chatbot frontend using React and Vite. The goal was not a visual redesign. The goal was a structural upgrade. Before: One index.html file handling the header, chat messages, input logic, styling and JavaScript. Everything in one place. After: Four focused components each with a single responsibility. App.jsx manages state and connects them. Component structure: Header.jsx — renders the app title and status indicator ChatWindow.jsx — renders the list of messages ChatBubble.jsx — renders one message with a copy button InputBox.jsx — manages the textarea and send button Three React concepts applied today: useState: Replaces manual DOM manipulation. Instead of using appendChild to add a new message div, I update the messages array using setMessages. React detects the change and re-renders automatically. The component always reflects the current state of the data. Props and lifting state up: The messages array and sendMessage function live in App.jsx because both ChatWindow and InputBox need access to them. App passes messages down to ChatWindow for display and sendMessage down to InputBox as onSend. Neither child manages data it does not own. Controlled inputs: The textarea value is controlled by React state. Every keystroke updates the input state via onChange. On submit, the value is sent to the API and the state resets to empty. Deployment change: Plain HTML deployment: Enable GitHub Pages in repository settings, point to the docs folder. React deployment: Install gh-pages, add homepage and deploy scripts to package.json, configure base path in vite.config.js, then run npm run deploy. The command builds the app, generates optimised static files and pushes them to the gh-pages branch automatically. 8 errors encountered today: 1. sendMessage not defined — passed as prop from App.jsx 2. Code pasted into wrong file — moved to correct component 3. Function name placed after parentheses — corrected syntax 4. class and onclick used instead of className and onClick — JSX attributes corrected 5. Container expanding on overflow instead of scrolling — fixed with #root CSS height constraint 6. Copy button not reflecting Copied state — added useState and setTimeout 7. Git ownership conflict on new project folder — resolved with safe.directory config 8. Branch named master instead of main — renamed before push The live app is visually identical to the original HTML version. That was the target. React migration done correctly is transparent to the user. The value is in the code architecture, not the interface. Day 13 tomorrow. #ReactJS #AIEngineering #BuildInPublic #100DaysOfCode #Nigeria #SoftwareEngineering #WebDevelopment
To view or add a comment, sign in
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development