🔗 Request Data (Query Parameters)
The <odac get> tag allows you to access URL query parameters directly in your views. This is useful for forms, filters, and pagination.
Getting Query Parameters
Use <odac get="key" /> to access URL query parameters:
Important: <odac get> is for query parameters (URL parameters), not for data from controllers. For controller data, use <odac var> (see Variables).
<!-- URL: /search?q=laptop&page=2 -->
<p>Search query: <odac get="q" /></p>
<p>Current page: <odac get="page" /></p>
How it works:
- User visits
/search?q=laptop&page=2 <odac get="q" />retrieves the value ofqparameter- If parameter doesn't exist, it returns empty string (no error)
Undefined Parameters
If a parameter doesn't exist, it safely returns an empty string:
<!-- URL: /products (no query parameters) -->
<odac get="search" />
<!-- Output: (empty string, no error) -->
This prevents errors when parameters are optional.
Difference: get vs var
<odac get> - Query Parameters (from URL):
<!-- URL: /search?q=laptop -->
<odac get="q" />
<!-- Output: laptop -->
<odac var> - Controller Data (from Odac.set()):
// Controller
Odac.set('productName', 'Laptop')
<!-- View -->
<odac var="productName" />
<!-- Output: Laptop -->
Processing Request Data in Controllers
While you can access query parameters directly in views with <odac get>, it's often better to process them in the controller:
// Controller: controller/search.js
module.exports = async function(Odac) {
// Get query parameters
const query = Odac.Request.get('q') || 'all products'
const page = parseInt(Odac.Request.get('page')) || 1
// Validate and process
const validatedQuery = query.trim()
const validatedPage = Math.max(1, page)
// Fetch results
const results = await Odac.DB.products
.where('name', 'like', `%${validatedQuery}%`)
.limit(20)
.offset((validatedPage - 1) * 20)
.get()
// Pass processed data to view
Odac.set({
query: validatedQuery,
page: validatedPage,
results: results
})
Odac.View.skeleton('main').set('content', 'search')
}
<!-- View: view/content/search.html -->
<h1>Search Results for "<odac var="query" />"</h1>
<p>Page <odac var="page" /></p>
<odac:for in="results" value="product">
<div class="product">
<h3><odac var="product.name" /></h3>
<p><odac var="product.price" /></p>
</div>
</odac:for>
Accessing Request Object
You can access the full Request object through the Odac object:
<!-- Request method -->
<p>Method: <odac var="Odac.Request.method" /></p>
<!-- Current URL -->
<p>URL: <odac var="Odac.Request.url" /></p>
<!-- Client IP -->
<p>IP: <odac var="Odac.Request.ip" /></p>
<!-- User agent -->
<p>Browser: <odac var="Odac.Request.headers['user-agent']" /></p>
Practical Examples
Search Form with Results
<!-- Search form -->
<form action="/search" method="GET">
<input
type="text"
name="q"
value="<odac get="q" />"
placeholder="Search products..."
>
<button type="submit">Search</button>
</form>
<!-- Display search query if exists -->
<odac:if condition="Odac.Request.get('q')">
<p>Showing results for: "<odac get="q" />"</p>
</odac:if>
Pagination
<script:odac>
const currentPage = parseInt(Odac.Request.get('page')) || 1
const totalPages = 10
</script:odac>
<div class="pagination">
<odac:if condition="currentPage > 1">
<a href="?page=<odac var="currentPage - 1" />">Previous</a>
</odac:if>
<span>Page <odac var="currentPage" /> of <odac var="totalPages" /></span>
<odac:if condition="currentPage < totalPages">
<a href="?page=<odac var="currentPage + 1" />">Next</a>
</odac:if>
</div>
Filter Form
<!-- URL: /products?category=electronics&sort=price&order=asc -->
<form action="/products" method="GET">
<select name="category">
<option value="">All Categories</option>
<option value="electronics" <odac:if condition="Odac.Request.get('category') === 'electronics'">selected</odac:if>>
Electronics
</option>
<option value="clothing" <odac:if condition="Odac.Request.get('category') === 'clothing'">selected</odac:if>>
Clothing
</option>
</select>
<select name="sort">
<option value="name" <odac:if condition="Odac.Request.get('sort') === 'name'">selected</odac:if>>
Name
</option>
<option value="price" <odac:if condition="Odac.Request.get('sort') === 'price'">selected</odac:if>>
Price
</option>
</select>
<button type="submit">Filter</button>
</form>
Active Navigation
<nav>
<a href="/" class="<odac:if condition="Odac.Request.url === '/'">active</odac:if>">
Home
</a>
<a href="/products" class="<odac:if condition="Odac.Request.url.startsWith('/products')">active</odac:if>">
Products
</a>
<a href="/about" class="<odac:if condition="Odac.Request.url === '/about'">active</odac:if>">
About
</a>
</nav>
Best Practices
- Validate in Controller: Always validate and sanitize request data in the controller before using it
- Default Values: Provide default values for optional parameters
- Type Conversion: Convert string parameters to appropriate types (numbers, booleans)
- Security: Never trust user input - always validate and escape
Good:
// Controller
const page = Math.max(1, parseInt(Odac.Request.get('page')) || 1)
const limit = Math.min(100, parseInt(Odac.Request.get('limit')) || 20)
Odac.set('page', page)
Odac.set('limit', limit)
Avoid:
<!-- Don't do complex logic in views -->
<odac:if condition="parseInt(Odac.Request.get('page')) > 0 && parseInt(Odac.Request.get('page')) < 100">
...
</odac:if>