DEV Community

Cover image for Beyond the Tutorials: A Realistic Look at Coding in the Real World – Part 4
asifbuetcse
asifbuetcse

Posted on

Beyond the Tutorials: A Realistic Look at Coding in the Real World – Part 4

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 interview 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.

Black cloud on the swagger front

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

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 -

$.Questions[0].Answers[0].isCorrect: [,…]
0: "The JSON value could not be converted to System.Boolean. Path: $.Questions[0].Answers[0].isCorrect | LineNumber: 0 | BytePositionInLine: 80."

So; it failed to convert isCorrect from string to boolean.

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 -

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: ['./survey-add.component.scss']
})
export class SurveyAddComponent implements OnInit {
  _client: HttpClientService;
  surveyForm = new FormGroup({
    Title: new FormControl(""),
    Questions: new FormArray(
      [
        new FormGroup(
          {
            Text: new FormControl(""),
            Answers: new FormArray(
              [
                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(
              [
                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(
              [
                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['Questions'] as FormArray;
  }

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

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

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

  cancel() {
    this.surveyForm = new FormGroup({
      title: new FormControl(),
      Questions: new FormArray(
        [
          new FormGroup(
            {
              Text: new FormControl(""),
              Answers: new FormArray(
                [
                  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(
                [
                  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(
                [
                  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),
                    }
                  ),
                ]
              )
            }
          ),
        ]
      ),
    });
  }
}

We have to change our surveyRepository also to enable it to save survey, questions and answers.

Tutorials_2

The implementation that I go for is like this -

using dev_test.DTOs;

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

        IEnumerable<Survey> ISurveyRepository.GetSurveys()
        {
            _databaseContext.Database.EnsureCreated();
            return _databaseContext.Survey.ToList();
        }

        void ISurveyRepository.PostSurveys(SurveyComposite survey)
        {
            Survey surv = new Survey
            {
                Title = survey.Title
            };
            _databaseContext.Add<Survey>(surv);
            _databaseContext.SaveChanges();
            foreach(var ques in survey.Questions)
            {
                Question q = new Question
                {
                    Text = ques.Text,
                    SurveyId = surv.Id
                };
                _databaseContext.Add<Question>(q);
                _databaseContext.SaveChanges();
                foreach(var ans in ques.Answers)
                {
                    Answer answer = new Answer
                    {
                        QuestionId = q.Id,
                        Text = ans.Text,
                        IsCorrect = ans.IsCorrect
                    };
                    _databaseContext.Add<Answer>(answer);
                    _databaseContext.SaveChanges();
                }
            }
        }
    }
}

We forgot to update CreatedDate and UpdatedDate for survey; so this code is also throwing an error for that.

So; we change our Survey model creation like this -

    Survey surv = new Survey
     {
                Title = survey.Title,
                CreatedDate = DateTime.Now,
                UpdatedDate = DateTime.Now
      };        

It's still giving us -
Invalid column name 'CreatedDate'.
Invalid column name 'UpdatedDate'.


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 - isActive; 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 CreatedDate
to created_date.
So; we change our db design again and edit all word1_word2 format into camelCase.
The code and updated scripts will be available at version_2.

This actually solves the issue of saving multiple users; multiple surveys and multiple question and answers.
But all we did is just created a skeleton to save some data.
And we have some issues here; for example -

  • 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.
  • Saving successfully doesn't do anything in the front end. It should give an success message or toast ad redirect to list page.
  • The save method is returning only a boolean. It should be corrected to send correct format data.
  • Validations are not handled properly.
  • Survey page should be dynamic. It is bulky and unmanageable at this time.
  • We should have ideally separated the DTOs and models for the backend project.
  • We didn't go for either code first or db first approach. We need to change that (we are going to code first).
  • No authentication and authorization is implemented.
  • There are some other issues with the code.

We will start to fix all of these in the code version_3 and onwards.

Other episodes in this series:
First Part
Second Part
Third Part
Fourth Part
And the code is given is updated into -
Github

Top comments (0)