1

I'm displaying the results of a survey in Angular and struggling with manipulating the data structure and how to perform math on each column of the table.

Numerous responses to the same survey will be collected in the database and the code below is used to display a summary of all the responses in table form to the survey administrator.

Each question within the survey has three answers:

  1. rating of lesson (1 - 10 : number)
  2. rating of instructor (1 - 10 : number)
  3. comments (string)

An example of how this array of objects is structured is below.

[ <- Whole survey response
  [  <- Question 1
     {
       question: "Introduction to Angular 4"
     },
     {
       answer : 7
     },
     {
       answer : 6
     },
     {
       answer : 'Good lesson!'
     }
   ],
   [  <- Question 2
     {
       question: "Structure of an Angular 4 Application"
     },
     {
       answer : 5
     },
     {
       answer : 2
     },
     {
       answer : 'Instructor went too quickly!'
     }
   ]
 ]

I'm currently outputting this into a table using this:

<ng-container *ngFor="let result of results; let rNumber = index;">
  <table>
    <tr *ngFor="let answer of result; let qNumber = index;">
        <td *ngFor="let singleanswer of answer" style="border: 1px solid #333">
            {{singleanswer.answer}}
        </td>
      </tr>
      <hr>
  </table>
</ng-container>

Which gives me a table containing all the answers for each response in the database:

7 6 Good lesson!

5 2 Instructor went too quickly!

I need to be able to populate a table with ALL question 1 responses and then output another table with all the question 2 responses in it.

Furthermore, I need to create an additional row at the bottom with the mean of the numerical values.

==edit== Codepen available here: https://codepen.io/Taylorsuk/pen/NvzwaP (codepen seems flakey - forked from here)

2
  • 2
    Will you Please provide your plnkr or jsFiddle. Commented Aug 23, 2017 at 13:19
  • 1
    @Swanand codepen here: codepen.io/Taylorsuk/pen/NvzwaP cheers. Commented Aug 23, 2017 at 13:57

1 Answer 1

1

I wouldn't try to use your that one model to display in different formats. Instead after you populate your initial model, then create new models that match your other sub views.

Assuming table one is grouped by question numbers, perform the following after this.results are set to create a list of answers grouped by question:

this.resultsGroupedByQuestions: { title: string, answers: [] } = [];

for (let res of this.results) {
   for (let i = 0, il = res.length; i < il; i++) {
      // if you know the number of questions then simplify this
      let question = this.resultsGroupedByQuestions[i];
      if (!question) {
          this.resultsGroupedByQuestions[i] = question = { 
              title: '', answers: [] 
          };
      }
      if (res[i].question) question.title = res[i].question;
      if (res[i].answer) queue.answer = res[i].answer;
   }
}

Use this for your ui to display the results:

<ng-container *ngFor="let question of resultsGroupedByQuestions; let qIndex = index">
  <strong>{{qIndex}}: {{question.title}}</strong>
  <ul>
    <li *ngFor="let answer of question.answers">
      {{answer}}
    </li>
  </ul>
<ng-container>

Again to produce the means, calculate them after you get the results. Array.reduce() is good for creating aggregate functions.

// I'm assuming you'll know what questions have numeric results
const numericQuestionIndexes = [0,1]

this.means = numericQuestionIndexes.map(index => {
    this.results.reduce((p, c) => p + (c[index].answer || 0), 0) / this.results.length;
});

On your bottom row just do something like this:

<tr>
  <td>Averages:</td>
  <td>{{means[0] | percent:'1-1'}}</td>
  <td>{{means[1] | percent:'1-1'}}</td>
  <td></td>
</tr>
Sign up to request clarification or add additional context in comments.

4 Comments

Actually I'm finding that the question.title is within the same array as the answers therefore inaccessible by {{question.title}} how can I move this up one level so it's accessible outside of this loop?
What an odd structure. Anyways. I updated my answer.
Would it be better to structure my data like this : codebin.it?s=599de33c6522050004000001. I have the freedom to do this.
What make a seperate object for the answer property, just have an array of strings, unless you're expecting more properties?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.