Having trouble achieving the expected result in the form array using Angular response

An exam platform was developed where administrators could create quizzes. However, when attempting to edit a quiz, not all questions and options were displayed in the form array from the response. Surprisingly, editing and accessing array data locally worked perfectly.

HTML:-

<div
  *ngFor="let list of trainingItemList; let i = index"
  cdkDrag
  class="orderTraining-list"
>
  <div
    (click)="getData(list.path,i,list.type,list.id,list.name,list.quizInstruction,list.quizTime,list.questionList, list.order)"
    class="orderTraining-box"
  >
    <span class="btn-icon"
      ><i
        class="buy-icon"
        [class.bi-videocam]="list.type == 'video/mp4'"
        [class.bi-wallpaper]="list.type == 'image/jpeg' && 'image/png'"
        [class.bi-question-answer]="list.type == 'quiz'"
      ></i></span
    >{{list.name}}
  </div>
</div>

TS:-

 ngOnInit() {
    this.id = this.route.snapshot.params['id'];
    if(this.id != null){
      this.createName = 'Update Changes';
      this.createTraining.editTraining(this.id).subscribe((response:any)=>{
        this.trainingForm.get('trainingName').setValue(response.name);
        this.trainingItemList = response.trainingItemList;
      })
    }
    this.createQuizForm();
    this.createForm();
  }


 trainingItemList: Array<TrainingItemList> = [];

getData(path, i, type,id, name, quizInstruction, quizTime, questionList) {
    this.index = i;
    this.type = type;
    if (type == 'image/jpeg') {
      this.format = 'image';
      this.show = true;
      this.showUpload = false;
      this.showDelete = true;
      this.showQuiz = false;
      this.url = 'http://api/training/getMedia?path=' + path;
    }
    if (type == 'video/mp4') {
      this.format = 'video';
      this.show = true;
      this.showUpload = false;
      this.showDelete = true;
      this.showQuiz = false;
      this.url = 'http://api/training/getMedia?path=' + path;
    }
    if (type == 'quiz') {
      this.showQuiz = true;
      this.showUpload = false;
      this.showDelete = false;
      this.show = false;
      this.quiz = true;
      this.quizForm.patchValue({
        id:id,
        name: name,
        order: this.position,
        type: type,
        path: null,
        quizTime: quizTime,
        quizInstruction: quizInstruction,
        questionList: questionList
      })
     
      // this.quizForm.controls['questionList'] = this.fb.array(questionList.map((i:QuestionList)=>this.fb.group({questionText : i.questionText, 
      //   optionList:this.fb.array(i.optionList.map((j:OptionList)=>this.fb.group(
      //     {optionText:j.optionText, isAnswer:j.isAnswer}
      //     ))) 
      // })));
      console.log(questionList);
      console.log(this.quizForm.value.questionList);
    }
  }

createQuizForm() {
    this.quizForm = this.fb.group({
      id:[''],
      name: ['', Validators.required],
      type: ['quiz'],
      path: [null],
      order: this.position,
      quizTime: ['', [Validators.required, Validators.pattern('^[1-9][0-9]*$')]],
      quizInstruction: ['', Validators.required],
      questionList: this.fb.array([this.initQuestions()]),
    })
  }

  initQuestions(): FormGroup {
    return this.fb.group({
      id:[''],
      questionText: ['', Validators.required],
      optionList: this.fb.array([this.initOptions()]),
      timestamp:['']
    })
  }

  initOptions(): FormGroup {
    return this.fb.group({
      id:[''],
      optionText: ['', Validators.required],
      isAnswer: ['true', Validators.required],
      timestamp:['']
    })
  }

export interface TrainingItemList {
  id:number,
  name: string,
  order: number,
  type: string,
  path: string,
  quizTime: number,
  quizInstruction: string,
  questionList: any
}

Output:- when receiving the response from the API in the getData function parameter questionList(getData(questionList)- https://i.sstatic.net/HhFjo.png

when simply editing the array without saving it into the API and calling the same function getData(questionList)-

https://i.sstatic.net/2pxly.png

As can be observed in the second Array above, only 1 question is retrieved whereas in the previous array there are 2 questions.

The output above is generated by the following code -

  console.log(questionList);
  console.log(this.quizForm.value.questionList);

Answer №1


  const retrieveQuestion = this.quizForm.get('questionList') as FormArray;

      retrieveQuestion.clear();
      questionList.forEach(item => {
        
        retrieveQuestion.push(
          this.fb.group({
            id:item.id,
            questionText:item.questionText,
            optionList:this.generateOptions(item)
          })
        )
      });

    }
  }

  generateOptions(data) {
    let newArr = new FormArray([])
    data.optionList.forEach(option => {
      newArr.push(this.fb.group({ 
        id:option.id,
        optionText:option.optionText,
        isAnswer:option.isAnswer
      }))
    })
    return newArr;
  }

By implementing this method, I am capable of accessing and updating nested arrays within a form for patching values.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Strategies for obtaining the return type of a map and only including the type S

How can I retrieve the return type of map and only display S? const initialState = { x: 1, y: 2 } type InitialStateType = typeof initialState type MapGetter<S, R, R1> = { map: (state: S) => R mapB?: (state: S) => R1 // more ... } ...

Angular application making a POST request to a Spring REST API

I have developed a RESTful API using Spring Boot and a client application using Angular 4. Both applications are currently running locally. When testing the POST method with Postman, it functions correctly. However, when attempting to make a POST request f ...

The utilization of a Typescript Generic for basic addition is not producing the desired results

This issue feels incredibly insignificant, but for some reason I can't seem to figure out why it's not functioning correctly. It seems like the return type should match since I am simply concatenating or adding based on whether it's a number ...

Troubleshooting 'Connection "default" was not found' error while mocking getManager in NestJS service unit testing

Currently undergoing unit testing for my NestJS Service with an entity named 'User'. I have created a simple Service to interact with a MS SQL server, setting up GET and POST endpoints in the Controller. One of the service methods I am focusing ...

Exploring new ways to customize Nebular styles within an nb-user tag

I've been struggling to adjust the font-weight and border-radius of a nb-user tag without any luck. I attempted to add a class and make changes in the .scss file, but nothing seemed to work This is the HTML <div class="teachers-box" *ngF ...

Automatically convert TypeScript packages from another workspace in Turborepo with transpilation

I have set up a Turborepo-based monorepo with my primary TypeScript application named @myscope/tsapp. This application utilizes another TypeScript package within the same repository called @myscope/tspackage. For reference, you can view the example reposit ...

JSDoc encounters issues when processing *.js files that are produced from *.ts files

I am currently working on creating documentation for a straightforward typescript class: export class Address { /** * @param street { string } - excluding building number * @param city { string } - abbreviations like "LA" are acceptable ...

How can I eliminate HTML elements from a string using JavaScript?

Currently, I am utilizing the rich text editor feature of the primeng library. It automatically converts any text I input into HTML format. However, there are instances when I need to display this content in plain text. Is there a straightforward method in ...

Utilizing an AwsCustomResource in AWS CDK to access JSON values from a parameter store

I found a solution on Stack Overflow to access configurations stored in an AWS parameter. The implementation involves using the code snippet below: export class SSMParameterReader extends AwsCustomResource { constructor(scope: Construct, name: string, pr ...

When employing a string union, property 'X' exhibits incompatibility among its types

In my code, I have two components defined as shown below: const GridCell = <T extends keyof FormValue>( props: GridCellProps<T>, ) => { .... } const GridRow = <T extends keyof FormValue>(props: GridRowProps<T>) => { ... & ...

How can the adapter pattern be implemented in Angular when dealing with an HTTP response containing an array of objects?

Using the adapter pattern in Angular, I have successfully adapted Http response to an 'Invoice' object. However, I am facing a challenge when one of the properties inside the 'Item' is an array. In this scenario, the 'items' ...

Problem with Rx.ReplaySubject subscription: callback is not triggering

In my project, I have a ReplaySubject from rxjs that emits a value or null based on the environment. This means that if I am in a certain environment, a service call is made to fetch data and emit it. If not, null is just emitted using next(null) on the re ...

How can we encapsulate the dx-data-grid along with its tools within a separate component and effectively manage it as a controller component?

We've been working on an angular application using devexpress.com. I'm trying to create a 'my-grid' controller with dx-data-grid, and I want to integrate dx-data-grid tools into it. However, I encountered an issue while attempting this. ...

What might be preventing combineLatest from executing?

Currently, I am attempting to run a block of code utilizing the combineLatest function. Within my translation library, there exists an RXJS Observable that is returned. Imported as individual functions are combineLatest, map, and tap. combineLatest(this. ...

Having trouble implementing object type switching in Typescript

While in the process of developing an angular application, I stumbled upon a peculiar issue. Some time ago, I crafted this piece of code which performed flawlessly: selectedGeoArea: any receiveStoreEvent(event) { switch (event.constructor) { ca ...

How come the information I receive when I subscribe always seems to mysteriously disappear afterwards?

I've been working on a web project using Angular, and I've run into an issue with my code that's been causing problems for a while now. The problem lies in fetching data from a server that contains translations: getTranslations(): Observab ...

Trouble with the Ngx-Captcha feature

I am currently utilizing https://www.npmjs.com/package/ngx-captcha/v/11.0.0. <ngx-recaptcha2 #captchaElem [siteKey]="'6Leh1ZIjAAAAAG8g0BuncTRT-VMjh3Y7HblZ9XSZ'" (success)="handleSuccess($event)" [useGlobalDomain]="fals ...

Ways to broaden the type signature of a Typescript comparator in order to facilitate sorting by properties nested within objects?

Here is a function that I created: arr.sort(alphabeticallyBy("name")) The function has the following signature: <T extends string>(prop: T) => (a: Partial<Record<T, string>>, b: Partial<Record<T, string>>) => ...

What impact do passing children have on the occurrence of Typescript errors?

Recently, I came across a peculiar situation where the Typescript compiler appeared to be confused by passing the children prop to a component, leading to unsafe behavior. I am looking to create a component that can only accept the subtitle (text) and sub ...

Where can I find the refresh token for Azure Single Sign-On with MSAL?

Currently, I am working on integrating SSO for my application using Angular and .NET 2.2. I have come across a roadblock with the refresh token. While the login process is functioning correctly and the service is sending a lot of login information, the ref ...