0

My previous question was about not being able to fetch data from DB but now I can see fetched data in console log. The new problem is that this data is not being displayed on my HTML page. Someone asked me about OPTIONS headers before my first request but in console I only see GET headers for the fonts. enter image description here

browse.component.html

<div><ul style="list-style-type: none; color: whitesmoke;">
         <li>OS</li>
      <li *ngFor="let item of Categories; let i = index ">
           <a>{{item.NAME_OS}}</a>
         </li>
</ul>
</div>

browse.component.ts

import { Component, OnInit } from '@angular/core';
import {Category} from '../shared/category';
import {TovarService} from '../shared/tovar.service';
import { NgModule } from '@angular/core';
@Component({
 selector: 'app-browse',
 templateUrl: './browse.component.html',
 styleUrls: ['./browse.component.css']
})
export class BrowseComponent implements OnInit {
 Categories: Category[];
 constructor(private tovarservice: TovarService) {
   this.Categories = [];
 }

 ngOnInit(){
   this.Categories = this.tovarservice.getCategory();
 }

}

category.ts

export class Category{
 NUM_OS: number;
 NAME_OS: string;
 constructor(NUM_OS: number, NAME_OS: string) {
   this.NUM_OS = NUM_OS;
   this.NAME_OS = NAME_OS;
 }
}

category.php

<?
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, PUT, POST, PATCH, DELETE, OPTIONS");
header('Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding, X-Auth-Token, content-type');
include('connection.php');
$result3=mysqli_query($connection, "SELECT NUM_OS, NAME_OS from OS") or die("can't retrieve");
if($result3){
 $rows = mysqli_num_rows($result3);
 $obj1 = array();
 for($i =0; $i <$rows; $i++){
   $row = mysqli_fetch_row($result3);
   $obj1[$i]["NUM_OS"] = $row[0];
   $obj1[$i]["NAME_OS"] = $row[1];
     }
 echo json_encode($obj1);
 mysqli_free_result($result3);

}
mysqli_close($connection);
?>

http.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { HttpResponse, HttpHeaders } from '@angular/common/http';
import { Observable} from 'rxjs';
import { map } from 'rxjs/operators';
import { catchError } from 'rxjs/operators';
import { Category } from './category';
import {enableProdMode} from '@angular/core';
import { throwError } from 'rxjs';
import {Product} from './product';

@Injectable()
export class HttpService{
 constructor(private http: HttpClient) {}
 getCategory(){
   return this.http.get('http://localhost/category.php').pipe(
     map(resp => resp),
     catchError((error: any) => throwError(error)));
 }
}

tovar.service.ts

import {Category} from './category';
import { Injectable } from '@angular/core';
import {HttpService} from './http.service';
import {Product} from './product';

@Injectable()
export class TovarService{
 Categories: Category[];

 constructor(private httpService: HttpService) {
   this.Categories = [];
 }
 getCategory = (): Category[] => {
   this.httpService.getCategory().subscribe((resp => {
     console.log('inside category', resp); return resp;
       for (let index in resp){
         let cat1: Category = new Category(resp[index].NUM_OS, resp[index].NAME_OS);
         this.Categories.push(cat1);
       }
     }));
   return this.Categories;
 }
}
user3783243
  • 5,368
  • 5
  • 22
  • 41
  • 2
    You're returning right after the console.log, so your code never enters the for loop to push into `this.Categories` – aynber Dec 24 '20 at 12:54
  • Check what inside `this.Categories` instead of `resp` – Robin Singh Dec 24 '20 at 12:55
  • Does this answer your question? [How do I return the response from an Observable/http/async call in angular?](https://stackoverflow.com/questions/43055706/how-do-i-return-the-response-from-an-observable-http-async-call-in-angular) – R. Richards Dec 24 '20 at 12:55

2 Answers2

0

httpService.getCategory() fills Categories inside an inner subscription. When your component's ngOnInit is running, the service level this.Categories is empty.

I don't see a real point on keeping Categories in both service and component. The simplest solution would be to replace this:

<li *ngFor="let item of Categories; let i = index ">
     <a>{{item.NAME_OS}}</a>
</li>

With (After changing the access modifier of tovarService to public):

<li *ngFor="let item of tovarService.Categories; let i = index ">
     <a>{{item.NAME_OS}}</a>
</li>

However, I'd probably remove the array-related logic from the service and return the Observable itself from the service, then handle the array in the component.

noamyg
  • 2,747
  • 1
  • 23
  • 44
0

Changed the variables to uppercase because fields of the Category table were in uppercase. Everythig works now