Search code examples
angulartypescriptflask-restful

Getting JSON from Flask to Angular


So i started to try out Angular 4 days ago.

Now im so far that I want to get some juicy JSON data from my Backend Flask Server to my Frontend Angular.

Problem is that

  1. The JSON data is not saved into my variable
  2. It cannot be iterated over

I don't know what im doing wrong and seek your help now.

The JSON File has this structure.

{"id":[1,2,3],"name":["Test 1","Test 2","Test 3"]}

In my browser it shows.

Error: "Error trying to diff 'Test 1,Test 2,Test 3'. Only arrays and iterables are allowed"

In the question I asked before the commentors pointed out that it is not an array that Im using so i can not iterate over tests.

<ul>
  <li *ngFor="let test of tests">
          <a routerLink="/detail/{{test.id}}">
          <span>{{test.id}}</span> {{test.name}}
          </a>
  </li>
</ul>

But when this code is changed to

<ul>
  <li *ngFor="let test of tests.id">
          <a routerLink="/detail/{{test}">
          <span>{{test.id}}</span> 
          </a>
  </li>
</ul>

An error shows up when trying to build. Saying error TS2339: Property 'id' does not exist on type 'Test[]'.

But the interface has defined these (id and name), so the only thing that I conclude from this is that tests must be empty.

My tests.service.ts should get an Observable array of Type Test

...
import { HttpClient, HttpHeaders } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class TestService {

private testUrl = 'http://my.server/tests';

constructor(
  private http: HttpClient
  ) { }

getTests(): Observable<Test[]> {
        return this.http.get<Test[]>(this.testUrl);
        }
...

And with this one it is planned to subscribe to the service in my tests.component.ts

...
@Component({
  selector: 'app-tests',
  templateUrl: './tests.component.html',
  styleUrls: ['./tests.component.css']
})
export class TestsComponent implements OnInit {
  tests: Test[];

  getTests(): void {
        this.testService.getTests()
                .subscribe(tests => this.tests = tests);

  }


  constructor(private testService: TestService) { }

  ngOnInit(): void {
  this.getTests();
  }

}

Test interface that gets used.

export interface Test {
   id: number;
   name: string;
}

Console.log(tests) returns empty.

Maybe someone of you can be so helpful and point out where this thing goes wrong.

Cheers!

Edit:

Added test interface.


Solution

  • If you have an array of test, the code has an error:

    <ul>
      <li *ngFor="let test of tests.id">
              <a routerLink="/detail/{{test}">
              <span>{{test.id}}</span> 
              </a>
      </li>
    </ul>
    

    Must be:

    <ul>
      <li *ngFor="let test of tests">
              <a routerLink="/detail/{{test.id}">
              <span>{{test.id}}</span> 
              </a>
      </li>
    </ul>
    

    Because each test has the property id. And if the file has this structure:

    {"id":[1,2,3],"name":["Test 1","Test 2","Test 3"]} based of your code the response, must be:

    [
       {'id': 1, name: 'Test 1'},
       ...
    ]
    

    You need to transforme the file of process the return when service return the data.

    You can process your response:

    a.id.map( item => {return {"id": item, "name": a.name[item - 1]}} )
    0: Object { id: 1, name: "Test 1" }
    1: Object { id: 2, name: "Test 2" }
    2: Object { id: 3, name: "Test 3" }