API Requests with odac.js
Learn how to make GET and POST requests to your API endpoints using odac.js.
GET Requests
Basic GET Request
odac.get('/api/data', function(response) {
console.log('Data:', response)
})
With Parameters
const userId = 123
odac.get(`/api/users/${userId}`, function(user) {
console.log('User:', user.name)
console.log('Email:', user.email)
})
Error Handling
odac.get('/api/data', function(response) {
if (response.error) {
console.error('Error:', response.error)
return
}
// Process data
console.log('Success:', response)
})
POST Requests
Using Forms
The recommended way to make POST requests is using Odac.form():
odac.form('#my-form', function(data) {
if (data.result.success) {
console.log('Success!')
}
})
See Form Handling for details.
Manual POST (Advanced)
For custom POST requests without forms, use the internal AJAX method:
// Note: This is an advanced pattern
// For most cases, use odac.form() instead
const formData = new FormData()
formData.append('name', 'John')
formData.append('email', 'john@example.com')
formData.append('_token', odac.token())
fetch('/api/submit', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
console.log('Success:', data)
})
CSRF Protection
Automatic Token Management
odac.js automatically handles CSRF tokens:
// Token is automatically included
odac.get('/api/data', function(response) {
// ...
})
// Token is automatically included in forms
odac.form('#my-form', function(data) {
// ...
})
Manual Token Access
If you need the token manually:
const token = odac.token()
console.log('Current token:', token)
Common Patterns
Fetching Data
// Get user profile
odac.get('/api/profile', function(profile) {
document.querySelector('#username').textContent = profile.name
document.querySelector('#email').textContent = profile.email
})
Loading List Data
// Get products
odac.get('/api/products', function(products) {
const container = document.querySelector('#products')
products.forEach(product => {
const html = `
<div class="product">
<h3>${product.name}</h3>
<p>${product.price}</p>
</div>
`
container.insertAdjacentHTML('beforeend', html)
})
})
Search
const searchInput = document.querySelector('#search')
searchInput.addEventListener('input', function() {
const query = this.value
if (query.length < 3) return
odac.get(`/api/search?q=${encodeURIComponent(query)}`, function(results) {
displayResults(results)
})
})
function displayResults(results) {
const container = document.querySelector('#results')
container.innerHTML = ''
results.forEach(result => {
const html = `<div class="result">${result.title}</div>`
container.insertAdjacentHTML('beforeend', html)
})
}
Autocomplete
let debounceTimer
document.querySelector('#autocomplete').addEventListener('input', function() {
clearTimeout(debounceTimer)
const value = this.value
debounceTimer = setTimeout(() => {
if (value.length < 2) return
odac.get(`/api/autocomplete?q=${value}`, function(suggestions) {
showSuggestions(suggestions)
})
}, 300)
})
Infinite Scroll
let page = 1
let loading = false
window.addEventListener('scroll', function() {
if (loading) return
const scrollPosition = window.innerHeight + window.scrollY
const threshold = document.body.offsetHeight - 500
if (scrollPosition >= threshold) {
loadMore()
}
})
function loadMore() {
loading = true
page++
odac.get(`/api/posts?page=${page}`, function(posts) {
posts.forEach(post => {
appendPost(post)
})
loading = false
})
}
Real-time Updates
// Poll for updates every 30 seconds
setInterval(function() {
odac.get('/api/notifications', function(notifications) {
updateNotificationBadge(notifications.count)
})
}, 30000)
Server-Side Setup
GET Endpoint
// controller/get/users.js
module.exports = function(Odac) {
// Get all users
const users = [
{id: 1, name: 'John', email: 'john@example.com'},
{id: 2, name: 'Jane', email: 'jane@example.com'}
]
return users
}
// route/www.js
odac.Route.get('/api/users', 'users')
GET with Parameters
// controller/get/user.js
module.exports = async function(Odac) {
const userId = odac.Request.data.url.id
// Fetch user from database
const user = await getUserById(userId)
if (!user) {
odac.Request.status(404)
return {error: 'User not found'}
}
return user
}
// route/www.js
odac.Route.get('/api/users/{id}', 'user')
POST Endpoint
// controller/post/create.js
module.exports = async function(Odac) {
const name = await odac.Request.request('name')
const email = await odac.Request.request('email')
// Validation
if (!name || !email) {
return {
result: {success: false},
errors: {
name: !name ? 'Name is required' : null,
email: !email ? 'Email is required' : null
}
}
}
// Create user
const user = await createUser({name, email})
return {
result: {
success: true,
message: 'User created successfully'
},
user: user
}
}
// route/www.js
odac.Route.post('/api/users/create', 'create')
Response Format
Success Response
{
"result": {
"success": true,
"message": "Operation successful"
},
"data": {
"id": 123,
"name": "John"
}
}
Error Response
{
"result": {
"success": false,
"message": "Validation failed"
},
"errors": {
"email": "Email is required",
"password": "Password must be at least 8 characters"
}
}
Best Practices
- Use Appropriate Methods: GET for reading, POST for writing
- Validate Input: Always validate on the server
- Handle Errors: Provide meaningful error messages
- Use HTTPS: Always use HTTPS for sensitive data
- Rate Limiting: Implement rate limiting on the server
- Debounce Requests: Debounce rapid requests (search, autocomplete)
Advanced Techniques
Request Caching
const cache = {}
function getCached(url, callback) {
if (cache[url]) {
callback(cache[url])
return
}
odac.get(url, function(data) {
cache[url] = data
callback(data)
})
}
// Usage
getCached('/api/data', function(data) {
console.log('Data:', data)
})
Request Queue
const requestQueue = []
let processing = false
function queueRequest(url, callback) {
requestQueue.push({url, callback})
processQueue()
}
function processQueue() {
if (processing || requestQueue.length === 0) return
processing = true
const {url, callback} = requestQueue.shift()
odac.get(url, function(data) {
callback(data)
processing = false
processQueue()
})
}
Retry Logic
function getWithRetry(url, callback, maxRetries = 3) {
let attempts = 0
function attempt() {
attempts++
odac.get(url, function(data) {
if (data.error && attempts < maxRetries) {
setTimeout(attempt, 1000 * attempts)
} else {
callback(data)
}
})
}
attempt()
}
Troubleshooting
Request Not Working
- Check the URL is correct
- Verify the endpoint exists in your routes
- Check browser console for errors
- Ensure CSRF token is valid
CORS Errors
- CORS is not an issue for same-origin requests
- For cross-origin requests, configure server CORS headers
Token Errors
- Tokens are managed automatically
- If you get token errors, check server configuration
- Ensure cookies are enabled
Next Steps
- Learn about Form Handling
- Explore AJAX Navigation
- Check odac.js Overview