Skip to main content
GET
/
api
/
taskCategories
Get All Categories
curl --request GET \
  --url https://api.example.com/api/taskCategories
{
  "response": [
    {}
  ]
}

Endpoint

GET /api/taskCategories
Retrieves all task categories from the database. Returns an array of category objects with their IDs and names.

Query Parameters

This endpoint does not support query parameters. All categories are returned in a single response.

Response

response
array
An array of TaskCategory objects. Returns an empty array [] if no categories exist.

Status Codes

  • 200 OK - Successfully retrieved all categories

Examples

curl http://localhost:3000/api/taskCategories

Response Examples

[
  {
    "_id": "a1b2c3d4-e5f6-4a5b-8c9d-0e1f2a3b4c5d",
    "name": "Work"
  },
  {
    "_id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
    "name": "Personal"
  },
  {
    "_id": "c3d4e5f6-a7b8-4c9d-0e1f-2a3b4c5d6e7f",
    "name": "Shopping"
  },
  {
    "_id": "d4e5f6a7-b8c9-4d0e-1f2a-3b4c5d6e7f8a",
    "name": "Health"
  }
]

Usage Notes

This endpoint returns all categories without pagination. For most task management applications, the number of categories is typically small, making pagination unnecessary.
The special "uncategorized" value used in tasks is NOT a category object and will not appear in this list. It’s a string literal used as a default value for tasks without category assignments.

Common Use Cases

Populate Category Dropdown

async function loadCategoryDropdown(selectElement) {
  const response = await fetch('http://localhost:3000/api/taskCategories');
  const categories = await response.json();
  
  // Clear existing options
  selectElement.innerHTML = '';
  
  // Add uncategorized option
  const uncategorizedOption = document.createElement('option');
  uncategorizedOption.value = 'uncategorized';
  uncategorizedOption.textContent = 'Uncategorized';
  selectElement.appendChild(uncategorizedOption);
  
  // Add category options
  categories.forEach(category => {
    const option = document.createElement('option');
    option.value = category._id;
    option.textContent = category.name;
    selectElement.appendChild(option);
  });
}

Get Category by Name

async function findCategoryByName(name) {
  const response = await fetch('http://localhost:3000/api/taskCategories');
  const categories = await response.json();
  
  return categories.find(cat => 
    cat.name.toLowerCase() === name.toLowerCase()
  );
}

// Usage
const workCategory = await findCategoryByName('Work');
if (workCategory) {
  console.log('Work category ID:', workCategory._id);
}

Check if Category Exists

async function categoryExists(name) {
  const response = await fetch('http://localhost:3000/api/taskCategories');
  const categories = await response.json();
  
  return categories.some(cat => 
    cat.name.toLowerCase() === name.toLowerCase()
  );
}

// Usage
if (await categoryExists('Work')) {
  console.log('Work category already exists');
} else {
  // Create it
}

Sort Categories Alphabetically

const response = await fetch('http://localhost:3000/api/taskCategories');
const categories = await response.json();

// Sort by name
const sortedCategories = categories.sort((a, b) => 
  a.name.localeCompare(b.name)
);

console.log('Categories:', sortedCategories.map(c => c.name).join(', '));

Get Tasks Count per Category

async function getCategoriesWithTaskCount() {
  // Fetch both categories and tasks
  const [categoriesRes, tasksRes] = await Promise.all([
    fetch('http://localhost:3000/api/taskCategories'),
    fetch('http://localhost:3000/api/tasks')
  ]);
  
  const categories = await categoriesRes.json();
  const tasks = await tasksRes.json();
  
  // Count tasks per category
  const categoriesWithCount = categories.map(category => ({
    ...category,
    taskCount: tasks.filter(task => task.categoryId === category._id).length
  }));
  
  // Add uncategorized count
  const uncategorizedCount = tasks.filter(
    task => task.categoryId === 'uncategorized'
  ).length;
  
  return {
    categories: categoriesWithCount,
    uncategorized: uncategorizedCount
  };
}

// Usage
const data = await getCategoriesWithTaskCount();
data.categories.forEach(cat => {
  console.log(`${cat.name}: ${cat.taskCount} tasks`);
});
console.log(`Uncategorized: ${data.uncategorized} tasks`);

Build Category Map for Quick Lookup

async function buildCategoryMap() {
  const response = await fetch('http://localhost:3000/api/taskCategories');
  const categories = await response.json();
  
  // Create a Map for O(1) lookup
  const categoryMap = new Map();
  categories.forEach(category => {
    categoryMap.set(category._id, category.name);
  });
  
  return categoryMap;
}

// Usage
const categoryMap = await buildCategoryMap();
const categoryName = categoryMap.get('a1b2c3d4-e5f6-4a5b-8c9d-0e1f2a3b4c5d');
console.log('Category name:', categoryName);

Display Category List with Colors

async function displayCategoriesWithColors() {
  const response = await fetch('http://localhost:3000/api/taskCategories');
  const categories = await response.json();
  
  // Assign colors (you might store these in localStorage or a database)
  const colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A', '#98D8C8'];
  
  const categoriesWithColors = categories.map((category, index) => ({
    ...category,
    color: colors[index % colors.length]
  }));
  
  return categoriesWithColors;
}

Integration Examples

React Component

import { useState, useEffect } from 'react';

function CategoryList() {
  const [categories, setCategories] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  
  useEffect(() => {
    async function fetchCategories() {
      try {
        const response = await fetch('http://localhost:3000/api/taskCategories');
        
        if (!response.ok) {
          throw new Error('Failed to fetch categories');
        }
        
        const data = await response.json();
        setCategories(data);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    }
    
    fetchCategories();
  }, []);
  
  if (loading) return <div>Loading categories...</div>;
  if (error) return <div>Error: {error}</div>;
  
  return (
    <ul>
      {categories.map(category => (
        <li key={category._id}>{category.name}</li>
      ))}
    </ul>
  );
}

Vue Component

export default {
  data() {
    return {
      categories: [],
      loading: true,
      error: null
    };
  },
  async mounted() {
    try {
      const response = await fetch('http://localhost:3000/api/taskCategories');
      this.categories = await response.json();
    } catch (error) {
      this.error = error.message;
    } finally {
      this.loading = false;
    }
  }
};

Caching Strategies

// Simple in-memory cache with expiration
const categoryCache = {
  data: null,
  timestamp: null,
  ttl: 5 * 60 * 1000 // 5 minutes
};

async function getCategoriesWithCache() {
  const now = Date.now();
  
  // Return cached data if still valid
  if (categoryCache.data && 
      categoryCache.timestamp && 
      now - categoryCache.timestamp < categoryCache.ttl) {
    console.log('Returning cached categories');
    return categoryCache.data;
  }
  
  // Fetch fresh data
  console.log('Fetching fresh categories');
  const response = await fetch('http://localhost:3000/api/taskCategories');
  const categories = await response.json();
  
  // Update cache
  categoryCache.data = categories;
  categoryCache.timestamp = now;
  
  return categories;
}

Performance Tips

Cache Categories: Since categories don’t change frequently, consider caching them in memory or localStorage to reduce API calls.
Fetch in Parallel: When loading a page that needs both tasks and categories, fetch them in parallel using Promise.all() for better performance.

Build docs developers (and LLMs) love