Приложение работает нормально, но консоль, кажется, отображает эту ошибку каждый раз, когда я обновляюсь:
ПОЛУЧИТЬ http://localhost:4200/[object%20Object] 404 (не найдено) @ lists.component.html:3 (кажется, ссылается на 3-ю строку html-кода ниже)
Я полагаю, что HTML пытается отобразить переменную l.image до того, как она будет правильно инициализирована с помощью запроса GET из локального SQL?
Мое приложение по существу использует Angular для запроса JS-сервера node, который возвращает результат SQL-запроса. Заранее спасибо.
Угловой код
export class ListsComponent implements OnInit {
lists:any
constructor(private http: HttpClient, private router: Router, private cloud: Cloud, private sanitizer: DomSanitizer) {
this.getImages()
}
ngOnInit() {
}
async getImages(){
this.lists = await this.http.get<any>('/lists').toPromise()
}
JS-код узла
app.get('/lists', async (req, resp) => {
const conn = await pool.getConnection()
try {
const [ result, _ ] = await conn.query(SQL_SELECT_ALL_FROM_LISTS)
resp.status(200)
resp.type('application/json').send(result)
} catch(e) {
console.error('ERROR: ', e)
resp.status(500)
resp.end()
} finally {
conn.release()
}
})
HTML
<li *ngFor = "let l of lists" class = "list-group-item d-flex justify-content-between align-items-center">
<img *ngIf = "l.image !== 'undefined'" [src] = "l.image" class = "img-thumbnail img-fluid" width = "10%">
<a (click) = "routeToTasks(l.listID, l.listName)" class = "list-group-item list-group-item-action list-group-item-primary">{{l.listName}}</a>
<button type = "button" class = "btn btn-danger" (click) = "deleteList(l.listID)">Delete</button>
</li>
Две вещи, которые вы можете сделать. Вместо вызова this.getImages()
из constructor
вызовите его из ngOnInit
и заверните li
внутрь ng-content
<ng-content *ngIf = "list">
<li *ngFor = "let l of lists"
class = "list-group-item d-flex justify-content-between align-items-center">
<img *ngIf = "l.image !== 'undefined'" [src] = "l.image" class =
"img-thumbnail img-fluid" width = "10%" >
<a (click) =
"routeToTasks(l.listID, l.listName)" class = "list-group-item
list-group-item-action list-group-item-primary"> {{l.listName}} </a>
<button type = "button" class = "btn btn-danger" (click) =
"deleteList(l.listID)"> Delete </button> </li> </ng-content>
</li>
</ng-content>
Вы визуализируете <li *ngFor = "let l of lists" >
, однако lists
не определено в начале.
Я бы посоветовал либо указать lists:any = []
, чтобы было начальное значение, и оно не отображало никаких дочерних объектов, либо вы могли бы использовать канал async
, который будет обрабатывать ожидание динамических данных:
<li *ngFor = "let l of lists | async" >
и удалите функцию toPromise()
from you
async getImages(){
this.lists = await this.http.get<any>('/lists')
}
Поскольку вы используете Angular
, подумайте об использовании Observable
В вашем коде это можно изменить на
export class ListsComponent implements OnInit {
lists:any[] = []; // Create an empty list
constructor(private http: HttpClient, private router: Router, private cloud: Cloud, private sanitizer: DomSanitizer) {
}
ngOnInit() {
this.getImages.subscribe(lists => this.lists = lists)
}
getImages = () => this.http.get<any[]>('/lists')
}
Обратите внимание на изменения;
Изменено lists:any
на lists:any[]
, так как мы ожидаем массив
заменил getImages()
на getImages = () => this.http.get<any[]>('/lists')
. Это функция, которая возвращает Observable
Вместо использования async/await
мы просто используем subscribe
Попробуйте использовать вопросительный знак непосредственно перед использованием оператора точки, как показано ниже:
<li *ngFor = "let l of lists" class = "list-group-item d-flex justify-content-between align-items-center">
<img *ngIf = "l?.image !== 'undefined'" [src] = "l?.image" class = "img-thumbnail img-fluid" width = "10%">
<a (click) = "routeToTasks(l.listID, l.listName)" class = "list-group-item list-group-item-action list-group-item-primary">{{l.listName}}</a>
<button type = "button" class = "btn btn-danger" (click) = "deleteList(l.listID)">Delete</button>
</li>
Я бы предложил добавить директиву ngIf в ваш html-компонент и сделать значение истинным, как только вы получите ответ с сервера.
<div *ngIf = "displayDetails">
<li *ngFor = "let l of lists"
...
</div>
В вашем компоненте, как только вы получите ответ от сервера, сделайте детали отображения истинными.
displayDetails:boolean = false;
this.getImages.subscribe(lists => {
this.lists = lists ;
this.displayDetails = true;
)}