Beyond the Tutorials: A Realistic Look at Coding in the Real World – Part 4
Tags: programming, tutorial, dotnetcore, angular
Published: 2023-01-28 12:26:21

<!-- wp:paragraph -->
<p>Programming tutorials shows us a land of promise where everything happens as you think; as soon as you think. But real world doesn’t work that way most of the times. Here; you spend hours debugging some CORS error or thinking why your database table Id column is not auto-incrementing. For the last 2 days; I am participating in a coding&nbsp;<a href="https://asifulhaque.com/common-interview-questions-for-sr-software-engineers-and-how-to-answer-them/">interview</a>&nbsp;which spans 2 days and these series of blog is based on that experience – what am I thinking at each stage; what is the issue and how I am resolving them. This is the fourth part of that.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Black cloud on the swagger front</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>When we tried to run the backend project; the swagger returned a 500 error. <br>Few things were missing in SurveyController.cs class -<br>1 <code>[ApiController]<br>[Route("api/[controller]")]</code> was missing before the <code>public class SurveyController : Controller</code> line and <br>2. [HttpGet] and [HttpPost] was absent before the method signatures; as I created the file from a wrong template.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Now after solving this issues; when we try to submit the survey form from the front-end; it is giving us 400 error. Yikes! Roaming around in the preview tab of browser; we can see the issue - </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><code>$.Questions[0].Answers[0].isCorrect: [,…]<br>0: "The JSON value could not be converted to System.Boolean. Path: $.Questions[0].Answers[0].isCorrect | LineNumber: 0 | BytePositionInLine: 80."</code><br>So; it failed to convert isCorrect from string to boolean.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>So; we gave them a Boolean value. After that; all of the string value - title, text etc was expecting default value except null; and we had to make them uppercase as to match them with backend model. So the final ts file for survey looks like this that can post to the backend - </p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>import { Component, OnInit } from '@angular/core';
import { FormArray, FormControl, FormGroup } from '@angular/forms';
import { HttpClientService } from 'src/app/http-client.service';

@Component({
  selector: 'app-survey-add',
  templateUrl: './survey-add.component.html',
  styleUrls: &#91;'./survey-add.component.scss']
})
export class SurveyAddComponent implements OnInit {
  _client: HttpClientService;
  surveyForm = new FormGroup({
    Title: new FormControl(""),
    Questions: new FormArray(
      &#91;
        new FormGroup(
          {
            Text: new FormControl(""),
            Answers: new FormArray(
              &#91;
                new FormGroup(
                  {
                    Text: new FormControl(""),
                    isCorrect: new FormControl(false),
                  }
                ),
                new FormGroup(
                  {
                    Text: new FormControl(""),
                    isCorrect: new FormControl(false),
                  }
                ),
                new FormGroup(
                  {
                    Text: new FormControl(""),
                    isCorrect: new FormControl(false),
                  }
                ),
                new FormGroup(
                  {
                    Text: new FormControl(""),
                    isCorrect: new FormControl(false),
                  }
                ),
              ]
            )
          }
        ),
        new FormGroup(
          {
            Text: new FormControl(""),
            Answers: new FormArray(
              &#91;
                new FormGroup(
                  {
                    Text: new FormControl(""),
                    isCorrect: new FormControl(false),
                  }
                ),
                new FormGroup(
                  {
                    Text: new FormControl(""),
                    isCorrect: new FormControl(false),
                  }
                ),
                new FormGroup(
                  {
                    Text: new FormControl(""),
                    isCorrect: new FormControl(false),
                  }
                ),
                new FormGroup(
                  {
                    Text: new FormControl(""),
                    isCorrect: new FormControl(false),
                  }
                ),
              ]
            )
          }
        ),
        new FormGroup(
          {
            Text: new FormControl(""),
            Answers: new FormArray(
              &#91;
                new FormGroup(
                  {
                    Text: new FormControl(""),
                    isCorrect: new FormControl(false),
                  }
                ),
                new FormGroup(
                  {
                    Text: new FormControl(""),
                    isCorrect: new FormControl(false),
                  }
                ),
                new FormGroup(
                  {
                    Text: new FormControl(""),
                    isCorrect: new FormControl(false),
                  }
                ),
                new FormGroup(
                  {
                    Text: new FormControl(""),
                    isCorrect: new FormControl(false),
                  }
                ),
              ]
            )
          }
        ),
      ]
    ),
  });

  constructor(client: HttpClientService) { this._client = client }

  ngOnInit(): void {
  }

  getQuestionControls() {
    return this.surveyForm.controls&#91;'Questions'] as FormArray;
  }

  getAnswerControls(question: any) {
    console.log(question&#91;'Answers'] as FormArray);
    return question&#91;'Answers'];
  }

  selectAnswer(i: number, j: number) {
  }

  save() {
    this._client.postData("survey", this.surveyForm.value).subscribe((res) =&gt; {
      console.log(res);
    });
  }

  cancel() {
    this.surveyForm = new FormGroup({
      title: new FormControl(),
      Questions: new FormArray(
        &#91;
          new FormGroup(
            {
              Text: new FormControl(""),
              Answers: new FormArray(
                &#91;
                  new FormGroup(
                    {
                      Text: new FormControl(""),
                      isCorrect: new FormControl(false),
                    }
                  ),
                  new FormGroup(
                    {
                      Text: new FormControl(""),
                      isCorrect: new FormControl(false),
                    }
                  ),
                  new FormGroup(
                    {
                      Text: new FormControl(""),
                      isCorrect: new FormControl(false),
                    }
                  ),
                  new FormGroup(
                    {
                      Text: new FormControl(""),
                      isCorrect: new FormControl(false),
                    }
                  ),
                ]
              )
            }
          ),
          new FormGroup(
            {
              Text: new FormControl(""),
              Answers: new FormArray(
                &#91;
                  new FormGroup(
                    {
                      Text: new FormControl(""),
                      isCorrect: new FormControl(false),
                    }
                  ),
                  new FormGroup(
                    {
                      Text: new FormControl(""),
                      isCorrect: new FormControl(false),
                    }
                  ),
                  new FormGroup(
                    {
                      Text: new FormControl(""),
                      isCorrect: new FormControl(false),
                    }
                  ),
                  new FormGroup(
                    {
                      Text: new FormControl(""),
                      isCorrect: new FormControl(false),
                    }
                  ),
                ]
              )
            }
          ),
          new FormGroup(
            {
              Text: new FormControl(""),
              Answers: new FormArray(
                &#91;
                  new FormGroup(
                    {
                      Text: new FormControl(""),
                      isCorrect: new FormControl(false),
                    }
                  ),
                  new FormGroup(
                    {
                      Text: new FormControl(""),
                      isCorrect: new FormControl(false),
                    }
                  ),
                  new FormGroup(
                    {
                      Text: new FormControl(""),
                      isCorrect: new FormControl(false),
                    }
                  ),
                  new FormGroup(
                    {
                      Text: new FormControl(""),
                      isCorrect: new FormControl(false),
                    }
                  ),
                ]
              )
            }
          ),
        ]
      ),
    });
  }
}
</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>We have to change our surveyRepository also to enable it to save survey, questions and answers. </p>
<!-- /wp:paragraph -->

<!-- wp:image {"id":933,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image size-large"><img src="https://asifulhaque.com/wp-content/uploads/2023/01/is-programming-hard-a-guide-to-getting-started-in-2022-scaled-1-1024x819.jpeg" alt="Tutorials_2" class="wp-image-933"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>The implementation that I go for is like this -</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>using dev_test.DTOs;

namespace dev_test.Repositories.Contracts
{
    public class SurveyRepository : ISurveyRepository
    {
        public DatabaseContext _databaseContext;
        public SurveyRepository(DatabaseContext databaseContext)
        {
            _databaseContext = databaseContext;
        }

        IEnumerable&lt;Survey&gt; ISurveyRepository.GetSurveys()
        {
            _databaseContext.Database.EnsureCreated();
            return _databaseContext.Survey.ToList();
        }

        void ISurveyRepository.PostSurveys(SurveyComposite survey)
        {
            Survey surv = new Survey
            {
                Title = survey.Title
            };
            _databaseContext.Add&lt;Survey&gt;(surv);
            _databaseContext.SaveChanges();
            foreach(var ques in survey.Questions)
            {
                Question q = new Question
                {
                    Text = ques.Text,
                    SurveyId = surv.Id
                };
                _databaseContext.Add&lt;Question&gt;(q);
                _databaseContext.SaveChanges();
                foreach(var ans in ques.Answers)
                {
                    Answer answer = new Answer
                    {
                        QuestionId = q.Id,
                        Text = ans.Text,
                        IsCorrect = ans.IsCorrect
                    };
                    _databaseContext.Add&lt;Answer&gt;(answer);
                    _databaseContext.SaveChanges();
                }
            }
        }
    }
}
</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>We forgot to update CreatedDate and UpdatedDate for survey; so this code is also throwing an error for that.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>So; we change our Survey model creation like this - </p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>    Survey surv = new Survey
     {
                Title = survey.Title,
                CreatedDate = DateTime.Now,
                UpdatedDate = DateTime.Now
      };        </code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>It's still giving us - <br><code>Invalid column name 'CreatedDate'.<br>Invalid column name 'UpdatedDate'.</code><br><br>The reason for this is in our db design. If we look closely; for all other two word terms; we used camel casing without any hyphen or underscore, like - <code>isActive</code>; which is the right way. But for these 2 dates; we used all lower case with underscore in between, like created_date. So; C# can't map <code>CreatedDate </code><br>to <code>created_date</code>.<br>So; we change our db design again and edit all <code>word1_word2</code> format into <code>camelCase</code>.<br>The code and updated scripts will be available at version_2.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This actually solves the issue of saving multiple users; multiple surveys and multiple question and answers.<br>But all we did is just created a skeleton to save some data. <br>And we have some issues here; for example -</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li>When saving the user with existing email; it throws an error; next time if we give different email; it saves correctly but skips an index in database.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Saving successfully doesn't do anything in the front end. It should give an success message or toast ad redirect to list page.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>The save method is returning only a boolean. It should be corrected to send correct format data.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Validations are not handled properly.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Survey page should be dynamic. It is bulky and unmanageable at this time.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>We should have ideally separated the DTOs and models for the backend project.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>We didn't go for either code first or db first approach. We need to change that (we are going to code first).</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>No authentication and authorization is implemented.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>There are some other issues with the code. </li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>We will start to fix all of these in the code version_3 and onwards. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>Other episodes in this series:</strong><br><a href="https://asifulhaque.com/when-programming-tutorials-doesnt-work-part-1/">First Part</a><br><a href="https://asifulhaque.com/beyond-the-tutorials-a-realistic-look-at-coding-in-the-real-world-part-2/">Second Part</a><br><a href="https://asifulhaque.com/beyond-the-tutorials-a-realistic-look-at-coding-in-the-real-world-part-3/">Third Part</a><br><a href="https://asifulhaque.com/beyond-the-tutorials-a-realistic-look-at-coding-in-the-real-world-part-4/">Fourth Part</a><br>And the code is given is updated into - <br><a href="https://github.com/asifbuetcse/dev-test" target="_blank" rel="noreferrer noopener">Github</a></p>
<!-- /wp:paragraph -->