Rahul Dagli
Rahul Dagli

Reputation: 4502

How to filter JSON data in angular 4

I'm trying to populate data on the page however, it's not getting rendered on the page. Instead its throwing an error msg:

core.es5.js:1020 ERROR SyntaxError: Unexpected token ' in JSON at position 322

question-card.component.ts

import { Component, OnInit } from '@angular/core';
import { RetrieveDataService } from '../retrieve-data.service';

@Component({
  selector: 'app-question-card',
  templateUrl: './question-card.component.html',
  styleUrls: ['./question-card.component.css']
})
export class QuestionCardComponent implements OnInit {
 question = '';
 questions = [];
  constructor(private retrieveDataService: RetrieveDataService) {
    this.appendContent();  
  }

  ngOnInit() {
  }

  appendContent(){
    for (var i = 0; i < 5; i++) {
      this.retrieveDataService.fetchData().subscribe(data=>{
            if (data[i].type == "question-card") {
                this.question = (data[i].question);
                this.questions.push(this.question);
            }
       });  
    }
  }
}

question-card.component.html

<div class="container" *ngFor="let question of questions">
<h3>{{question.section}}</h3>
</div>

retrieve-data.service.ts

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';

@Injectable()

export class RetrieveDataService {
  constructor(private http: Http) { 
  }
  fetchData(){
      return this.http.get('assets/page-content.json').map(
        (response) => response.json()
      )
  }
}

Page-content.json

[
    {
        "id": 1,
        "type": "question-card",
        "section": "some text comes here...",
        "headline": "some text comes here...",
        "question": "some text comes here...?",
        "options": ['<25%', '25-50%', '51-75%', '>75%'],
        "notes": "some text comes here..."
    },
    {
        "id": 2,
        "type": "question-flipping-card",
        "section": "some text comes here...",
        "headline": "some text comes here...",
        "options": ['<25%', '25-50%', '51-75%', '>75%']
    }
]

Upvotes: 2

Views: 16936

Answers (2)

eko
eko

Reputation: 40647

If you know the length of your json you can use let instead of var. let will preserve the i for that block scoped async operation. If you use var, then i will be the last value for all of your async operations:

appendContent(){
  this.retrieveDataService.fetchData().subscribe(data=>{
        for (let i = 0; i < data.length; i++) {
            if (data[i].type == "question-card") {
                this.questioncard = data[i];
                this.questionscard.push(this.questioncard);
            }
        } 
   });  

 }

}

html:

<div class="container" *ngFor="let q of questionscard">
   <h3>{{q?.section}}</h3>
</div>

Upvotes: 3

aifarfa
aifarfa

Reputation: 3939

updated

first thing first, you actually calls service many times. map and subscribe already iterate through response data, you don't need that for loop.

secondly, Angular will not updates HTML after Array mutation (Array.push or shift) you can either..

  1. set new value like this

    this.questions = [...this.questions, this.question]

  2. or use Observable pattern

try this

  appendContent() {
    this.retrieveDataService.fetchData() 
      .filter((item) => item.type === 'question-card') 
      .subscribe(data => {
        this.questions = [...this.questions, data]
      });
  }

read more sample here


original answer

in your json file.

{
 // .. 
 "options": ['<25%', '25-50%', '51-75%', '>75%'],
}

single quote ' is not valid JSON format

replace ' with "


from www.json.org

A value can be a string in double quotes, or a number, or true or false or null, or an object or an array. These structures can be nested.

Upvotes: 1

Related Questions