admin管理员组

文章数量:1323529

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-cardponent.ts

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

@Component({
  selector: 'app-question-card',
  templateUrl: './question-cardponent.html',
  styleUrls: ['./question-cardponent.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-cardponent.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 es here...",
        "headline": "some text es here...",
        "question": "some text es here...?",
        "options": ['<25%', '25-50%', '51-75%', '>75%'],
        "notes": "some text es here..."
    },
    {
        "id": 2,
        "type": "question-flipping-card",
        "section": "some text es here...",
        "headline": "some text es here...",
        "options": ['<25%', '25-50%', '51-75%', '>75%']
    }
]

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.ponent.ts

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

@Component({
  selector: 'app-question-card',
  templateUrl: './question-card.ponent.html',
  styleUrls: ['./question-card.ponent.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.ponent.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 es here...",
        "headline": "some text es here...",
        "question": "some text es here...?",
        "options": ['<25%', '25-50%', '51-75%', '>75%'],
        "notes": "some text es here..."
    },
    {
        "id": 2,
        "type": "question-flipping-card",
        "section": "some text es here...",
        "headline": "some text es here...",
        "options": ['<25%', '25-50%', '51-75%', '>75%']
    }
]
Share Improve this question edited Jul 13, 2017 at 11:38 eko 40.7k11 gold badges78 silver badges101 bronze badges asked Jul 13, 2017 at 11:03 Rahul DagliRahul Dagli 4,50216 gold badges51 silver badges89 bronze badges 6
  • use " instead of ' in the JSON. – seyid yagmur Commented Jul 13, 2017 at 11:14
  • Your i inside the for loop will always be 4 in your subscribe callback. And since your json does not have a data[4] right now it will be undefined. – eko Commented Jul 13, 2017 at 11:15
  • @echonax Could you please explain further along with example? – Rahul Dagli Commented Jul 13, 2017 at 11:18
  • @RahulDagli if you are using subscribe then this is an async operation. Async operations take time to plete. Let's say 100ms for sake of simplicity for this example. When i=0 you fire this request and it will take 100ms for the code to fall into the subscribe block. When it does indeed fall into the subscribe block(after 100ms) your for loop would already have been pleted. Because in 100ms a for loop can traverse maybe even the safe max integer value. Hence for all of the 5 fetchData requests your i will be the max value in the for loop. Check this: jsfiddle/dyyad3nd – eko Commented Jul 13, 2017 at 11:24
  • @echonax, Thanks for the explanation. So what's the prefered way to loop inside Async operation instead of for loop? – Rahul Dagli Commented Jul 13, 2017 at 11:27
 |  Show 1 more ment

2 Answers 2

Reset to default 3

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>

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

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.

本文标签: javascriptHow to filter JSON data in angular 4Stack Overflow