Render twig template with models of data retrieved from the database
Gabbyxo97 opened this issue · 9 comments
I was trying to...
Use my repository to get Posts from the database and rendering my Twig template with an array of Posts as data
@Get()
@Render('posts/index.twig')
async index() {
const posts:Post[] = await this._postRepository.findAll()
return {
'posts': posts
};
}This is my repo (nothing special but just to show what findAll returns
public async findAll(): Promise<Post[]> {
posts = [];
const rows = await this._database.query('SELECT * FROM posts');
for (const row in rows) {
posts.push(new Post(rows[row]));
}
return posts;
}And my model:
export default class Post {
private _id:number|null = null;
private _title:string = '';
private _body:string = '';
constructor(rowData: any = null) {
if (rowData != null) {
this._id = rowData.id;
this._title = rowData.title;
this._body = rowData.body;
}
}
get id(): number|null {
return this._id;
}
set id(id: number|null) {
this._id = id;
}
get title(): string {
return this._title;
}
set title(title: string) {
this._title = title;
}
get body(): string {
return this._body;
}
set body(body: string) {
this._body = body;
}
}And this is the part of my template where it loops the posts:
{% for post in posts %}
<tr>
<td>{{ post.id }}</td>
<td>{{ post.title }}</td>
<td>{{ post.body }}</td>
<td>
<a href="posts/edit/{{ post.id }}">Edit</a>
<a href="posts/delete/{{ post.id }}">Delete</a>
</td>
</tr>
{% endfor %}The problem:
If I loop over posts in my Twig template and I have the right amount of rows, but every table cell is empty. When I use {{ dump(post) }} in the loop, I get this:
object(3) {
[_id]=> number(2)
[_title]=> string(21) "Welcome to my website"
[_body]=> string(67) "This is still in BETA so shut up. But is cool I guess? Although..."
}
I know when using res.render with the normal routing it worked fine, but turns out now it doesn't. Is there any way to fix this, or am I doing something wrong or is this just intended behavior?
@Gabbyxo97 my two cents here: probably your response object gets serialized to json, so your getters are lost. Could you try without them? Or you can disable response transformation in the options.
@attilaorosz I added {transformRequest: false, transformResponse: false} to my Controller but still same output. I can use ._id _.title and _.body but for the future I'd need getters/other functions as well so I need to have it fixed
@Gabbyxo97 are you using the @controller or @jsoncontroller decorator?
@attilaorosz I'm using @controller:
import {Controller, Get, Render, Post as PostRoute, Req, Res, Session} from 'routing-controllers';
@Controller('/posts', {transformRequest: false, transformResponse: false})
export default class PostController {(just a headsup just in case, it's not an API server)
@Gabbyxo97 could you setup a repro repo? I tried to reproduce this locally and it seems to work fine.
@Gabbyxo97 I mocked out your db in the repository to return a fixed item like this:
public async findAll(): Promise<Post[]> {
const posts = [];
// const rows = await this._database.query('SELECT * FROM posts');
// for (const row in rows) {
// posts.push(new Post(rows[row]));
// }
return [new Post({id: 12, title: 'title', body: 'body'})];
}and it is working fine, got back this html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My website</title>
<link rel="stylesheet" href="css/posts.css" type="text/css">
</head>
<body>
<a href="posts/create">Create</a>
<table>
<thead>
<tr>
<th>ID</th>
<th>Title</th>
<th>Body</th>
<th></th>
</tr>
</thead>
<tbody>
object(3) {
[_id]=>
number(12)
[_title]=>
string(5) "title"
[_body]=>
string(4) "body"
}
<tr>
<td>12</td>
<td>title</td>
<td>body</td>
<td>
<a href="posts/edit/12">Edit</a>
<a href="posts/delete/12">Delete</a>
</td>
</tr>
</tbody>
</table>
</body>
</html>I modified the twig template a bit too for the test:
{% extends '../base.twig' %}
{% block stylesheets %}
<link rel="stylesheet" href="css/posts.css" type="text/css">
{% endblock %}
{% block content %}
<a href="posts/create">Create</a>
<table>
<thead>
<tr>
<th>ID</th>
<th>Title</th>
<th>Body</th>
<th></th>
</tr>
</thead>
<tbody>
{% for post in posts %}
{{ dump(post) }}
<tr>
<td>{{ post.id }}</td>
<td>{{ post.title }}</td>
<td>{{ post.body }}</td>
<td>
<a href="posts/edit/{{ post.id }}">Edit</a>
<a href="posts/delete/{{ post.id }}">Delete</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
Are you sure the db is returning what you expect?
@attilaorosz Whoop, IDK what went wrong, I tried changing it to use your mock, then it worked, but I changed it back into my db code and it still worked. Not sure what I did wrong last time, but it seems to work. Thanks! On towards my next issue.
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.