Search code examples
javascriptjsonangularangular12

How to restore data from json file in Angular 12


As a beginner developer, I am writing a simple quiz application using Angular 12 to improve my skills. I have a problem with restoring data with questions and answers from JSON file. It compiles successfully, but in the web browser I'm not getting any result and get such errors:

NG0303: Can't bind to 'ngForFrom' since it isn't a known property of 'div'
NG0303: Can't bind to 'ngForFrom' since it isn't a known property of 'div'

In the final result, it should appear the question text with answers in angular material cards and holding an event on the button which allows a user to move to the next question without changing the view. What am I doing wrong and is it a good way to do that and holding quiz data? Or maybe is some better way to store data and display it into angular material cards.

JSON Data:

[
    {
        "id": 0,
        "text": "Quis sit dolor tempor fugiat fugiat culpa qui?",
        "answer_A": "CORR",
        "answer_B": "INC",
        "answer_C": "INC",
        "answer_D": "INC"
    },
    {
        "id": 1,
        "text": "Quis tempor fugiat fugiat culpa aaa?",
        "answer_A": "INC",
        "answer_B": "INC",
        "answer_C": "CORR",
        "answer_D": "INC"
    }
]

HTML code:

<div *ngFor="let quizData from questions" class="question-grid-container">
  <mat-card class="question-card">
      <mat-card-title>Question {{ quizData.id }}</mat-card-title>
      <br>
      <mat-card-content>{{ quizData.text }}</mat-card-content>
      <mat-card-actions align="end">
          <button mat-button>Next Question</button>
      </mat-card-actions>
  </mat-card>
</div>

<div *ngFor="let quizData from questions" class="answers-grid-container"
    <mat-card class="answers">
       <mat-card-actions>
           <button class="btn-ans" mat-button>{{ quizData.answer_A }}</button>
      </mat-card-actions>
    </mat-card>
    <mat-card class="answers">
       <mat-card-actions>
           <button class="btn-ans" mat-button>{{ quizData.answer_B }}</button>
       </mat-card-actions>
   </mat-card>
   <mat-card class="answers">
       <mat-card-actions>
           <button class="btn-ans" mat-button>{{ quizData.answer_C }}</button>
       </mat-card-actions>
   </mat-card>
   <mat-card class="answers">
       <mat-card-actions>
           <button class="btn-ans" mat-button>{{ quizData.answer_D }}</button>
       </mat-card-actions>
   </mat-card>
</div>

TS class:

export class QuizComponent implements OnInit {
    quizData: IQuestionData[] = QuestionData;
}

Solution

  • quizData is the array that contains actual data, so it should be after of. Check *ngFor syntax

    Also There is no directive named as ngForFrom. Its ngForOf directive.

    So use *ngFor="let question of quizData".

    Try below HTML code

    <div *ngFor="let question of quizData" class="question-grid-container">
      <mat-card class="question-card">
          <mat-card-title>Question {{ question.id }}</mat-card-title>
          <br>
          <mat-card-content>{{ question.text }}</mat-card-content>
          <mat-card-actions align="end">
              <button mat-button>Next Question</button>
          </mat-card-actions>
      </mat-card>
    </div>
    
    <div *ngFor="let question of quizData" class="answers-grid-container"
        <mat-card class="answers">
           <mat-card-actions>
               <button class="btn-ans" mat-button>{{ question.answer_A }}</button>
          </mat-card-actions>
        </mat-card>
        <mat-card class="answers">
           <mat-card-actions>
               <button class="btn-ans" mat-button>{{ question.answer_B }}</button>
           </mat-card-actions>
       </mat-card>
       <mat-card class="answers">
           <mat-card-actions>
               <button class="btn-ans" mat-button>{{ question.answer_C }}</button>
           </mat-card-actions>
       </mat-card>
       <mat-card class="answers">
           <mat-card-actions>
               <button class="btn-ans" mat-button>{{ question.answer_D }}</button>
           </mat-card-actions>
       </mat-card>
    </div>