Error encountered in Angular CLI: Attempting to access property 'value' of an undefined variable

I am encountering an issue while trying to retrieve the values of radio buttons and store them in a MySql database. The error message I receive is

TypeError: Cannot read property 'value' of undefined
. This project involves the use of Angular and Express JS. In the server side, the query looks like this: app.post('/post', ...){
let sql = 'INSERT INTO results(question1, question2, question3)values("'+req.body.question1+'", "'+req.body.question2+'", "'+req.body.question3+'")';
}. The questions and options are already organized in a JSON file.

//data.json

[{
  "surveyid": 101,
  "surveyname": "Vitamin",
  "createdby": "Dr. Sarah",
  "createddate": "16-01-2018",
  "question": [{
      "questionid": 1,
      "questiondesc": "Q-1?",
      "qno": 1,
      "alloptions": [{
          "options": "A",
          "answer": "Yes"
        },
        {
          "options": "B",
          "answer": "No"
        }
      ]
    },

    {
      "questionid": 2,
      "questiondesc": "Q_2?",
      "qno": 2,
      "alloptions": [{
          "options": "A",
          "answer": "Yes"
        },
        {
          "options": "B",
          "answer": "No"
        },
        {
          "options": "C",
          "answer": "Don't know"
        }
      ]
    },

    {
      "questionid": 3,
      "questiondesc": "Q_3",
      "qno": 1,
      "alloptions": [{
          "options": "A",
          "answer": "Yes"
        },
        {
          "options": "B",
          "answer": "No"
        }
      ]
    }
  ]
}]

Subsequently, I populate all the questions and options into the HTML template.

<form>
  <div *ngFor="let items of jsonData">
    <div *ngFor="let items2 of items.question">
      <label>{{items2.questionid}}. {{items2.questiondesc}}</label>
      <div *ngFor="let items3 of items2.alloptions; let idx=index">
        <div class="radio">
          <input type="radio" name="question{{items2.questionid}}" [value]="items3.answer"><b>{{items3.options}}</b>. {{items3.answer}}
        </div>
      </div><br>
    </div>
  </div>
  <div align="center">
    <button type="button" class="btn btn-sm btn-success" (click)="submitResults(question1.value, question2.value, question3.value)">SUBMIT</button>
  </div>
</form>

Additionally, here are the service and component files:

//service.ts
getJsonData(): Observable < any > {
  return this.http.get('../assets/data.json')
    .map((res: Response) => res.json())
    .catch((error: any) => Observable.throw(error.json().error || 'server returns error'))
}

submitResults(question1: string, question2: string, question3: string) {
  return this.http.post('http://localhost:8000/newPush', {
    question1: question1,
    question2: question2,
    question3: question3
  });
}

//component.ts
jsonData = [];
getJsonData() {
  this.AppService.getJsonData().subscribe(
    data => console.log('json', this.jsonData = data),
    error => console.log('server returns error')
  );
}

submitResults(question1: string, question2: string, question3: string) {
  this.AppService.submitResults(question1, question2, question3);
}

If possible, could someone assist me with this issue? Please let me know if additional code snippets are required.

Answer №1

If you're not utilizing angular forms, you can retrieve values by accessing the form elements collection:

To start, you must grab the form element.

<form #myForm>

From there, you can access the values of the elements like this:

form.elements['question1'].value

Check out an example of a Native Form

Create an Angular template-driven form

1) Import FormsModule to your NgModule

import { FormsModule } from '@angular/forms';    

@NgModule({
  imports: [
    ...
    FormsModule
  ],
  ...
})
export class AppModule { }

2) Add a property of type Array in your component

answers: string[] = [];

3) Modify the template as follows:

<form #form="ngForm">
  <div *ngFor="let items of jsonData">
    <div *ngFor="let items2 of items.question; let i = index">
      <label>{{items2.questionid}}. {{items2.questiondesc}}</label>
      <div *ngFor="let items3 of items2.alloptions; let idx=index">
        <div class="radio">
          <input type="radio" 
            name="question{{items2.questionid}}"
            [(ngModel)]="answers[i]"                     
            [value]="items3.answer"><b>{{items3.options}}</b>. {{items3.answer}}
        </div>
      </div><br>
    </div>
  </div>
  <div align="center">
    <button type="button" class="btn btn-sm btn-success" (click)="pushResults(form.value)">
      SUBMIT
    </button>
  </div>
</form>
<pre>{{ form.value | json }}</pre>

View an example of a Template-driven Form

Implement an Angular model-driven Form

1) Similarly, import ReactiveFormsModule to your NgModule

import { ReactiveFormsModule} from '@angular/forms';    

@NgModule({
  imports: [
    ...
    ReactiveFormsModule
  ],
  ...
})
export class AppModule { }

2) Set up a FormGroup in your component

import { FormGroup, FormBuilder } from '@angular/forms';

@Component({
  ...
})
export class AppComponent {

  form: FormGroup;
  ...

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.form = this.fb.group({
      question1: '',
      question2: '',
      question3: ''
    })
  }

  pushResults(formValue) {
    console.log(formValue.question1, formValue.question2, formValue.question3);
  }
}

3) Adjust the template accordingly:

<form [formGroup]="form">
  <div *ngFor="let items of jsonData">
    <div *ngFor="let items2 of items.question; let i = index">
      <label>{{items2.questionid}}. {{items2.questiondesc}}</label>
      <div *ngFor="let items3 of items2.alloptions; let idx=index">
        <div class="radio">
          <input type="radio" 
              name="question{{items2.questionid}}"  
              formControlName="question{{i+1}}"
              [value]="items3.answer"><b>{{items3.options}}</b>. {{items3.answer}}
        </div>
      </div><br>
    </div>
  </div>
  <div align="center">
    <button type="button" class="btn btn-sm btn-success" (click)="pushResults(form.value)">
      SUBMIT
  </button>
  </div>
</form>
<pre>{{ form.value | json }}</pre>

See a Model-driven Form Example


If you just need one form, there's no need to import FormsModule or ReactiveFormsModule. However, for larger projects, it's recommended to leverage one of Angular's built-in methods.

Answer №2

Avoid using this within templates as it should only be used within components. In templates, all variables are expected to be component or class variables. Local variables cannot be accessed in templates. Instead, access member variables directly like this:

(click)="pushResults(question1.value, question2.value, question3.value)"

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

Incorporate the teachings of removing the nullable object key when its value is anything but 'true'

When working with Angular, I have encountered a scenario where my interface includes a nullable boolean property. However, as a developer and maintainer of the system, I know that this property only serves a purpose when it is set to 'true'. Henc ...

The dropdown on my website is malfunctioning

There seems to be an issue with my dropdown button. Previously, it only appeared when clicking on a specific part of the button. I attempted to resolve this problem but unfortunately, the dropdown no longer works at all and I am unable to revert my changes ...

Is Angular Translate susceptible to race conditions when using static files for multi-language support?

Currently utilizing angular translate with the static files loader for implementing multiple languages in my project. However, I've encountered a problem where the loading of language files sometimes takes longer than loading the actual view itself, l ...

Multer not running when file is uploaded in Node.js with Express using FormData

I have been working on uploading a video file to a local folder using form, multer, express, and nodejs. It seems that the video file successfully gets uploaded to the local folder each time I use the form. However, there is an issue with the code inside ...

Discover the solution for seamless integration of TypeScript with the novel `exports` and `main` field

I am currently utilizing Node.js version 16.10.0 along with TypeScript 4.5.5. As part of my development process, I am in the midst of publishing a library and have implemented the following configuration: "main": "./dist/index.js", ...

Generate interactive tables using data from an XML file

Hello, I'm in the process of generating tables from an XML file using Node.js with the Express framework. I am utilizing npm modules xmldom and xmldoc for this task. The objective is to present these data tables on an ejs page. Here is the structure ...

beforeSend method in jquery ajax synchronously calling

One of my functions is called: function callAjax(url, data) { $.ajax( { url: url, // same domain data: data, cache: false, async: false, // use sync results beforeSend: function() { // show loading indicator }, ...

Issue: The spy MovieService.getWatchListedMovies was expected to have been called during the angular Unit Testing, but it was

There is a component file named watchlist which relies on MovieService(service) to retrieve movies. Invoking ngOnInit() will trigger MovieService.getWatchlistedMovies() The component code is provided below, export class WatchlistComponent implements ...

Incorrect JavaScript switch case usage

Once again, I find myself with a question regarding JavaScript. This one seems to be an easy fix, but for some reason, I just can't seem to figure out what went wrong: I have a textbox and a button. When the button is clicked, the value should be pas ...

issue with eval() function

I am attempting to convert a JSON string from my .php file using the eval() function, but it is not working. The browser console shows a SyntaxError: expected expression, got '<'... However, when I comment out the line where eval() is used an ...

Do you need to align images side by side and have clickable images positioned beneath each one?

After searching high and low, I couldn't find a similar question. My goal is to transform this from a vertical layout to a horizontal one: https://i.stack.imgur.com/4kZNM.png Check out the code snippet below: ghost<br class="newline"> <img ...

Issues with navigation in React Native Typescript

Currently, I am in the process of developing a new React Native Expo project utilizing TypeScript. I have been attempting to configure navigation following the guidance provided in React Native's TypeScript documentation. However, upon running and sim ...

Error: Kinetic.js cannot upload image to canvas

There must be something simple that I'm missing here. I've checked my code line by line, but for some reason, the image just won't load. var displayImage = function(){ var stage = new Kinetic.Stage("imgarea", 250, 256); var layer = new ...

Unexpected lint errors are being flagged by TS Lint in Visual Studio Code out of nowhere

After a 5-week break from VS Code and my computer due to vacation, I was surprised to see TS lint errors popping up out of nowhere. These errors were completely incorrect and appearing in files that had previously been error-free. It's as if the linte ...

How to retrieve the value from an editable td within a table using Jquery

I am working with a dynamic table that looks like this: <table> <tbody> <tr> <td>1</td> <td contenteditable='true'>Value1</td> </tr> <tr> ...

The local machine is unable to access credentials from the /.aws/credentials directory

I recently generated a file named credentials.txt located at ~/.aws/credentials.txt. The contents of this file include: [bogdan-ses-user] aws_access_key_id = *** aws_secret_access_key = *** Establishing Node JS Server Locally const express = require(&apos ...

Trigger an event upon completion of a write operation in AngularJS

I want to trigger a search after my user finishes typing (without hitting enter) in AngularJS. Here is a simplified version of my HTML: <div ng-class="input-append" ng-controller="searchControl"> <input type="text" ng-model="ajaxSearch" ng-cha ...

Is it secure to utilize Http.Get (with parameters) for accessing WebApis in Angular 2/4?

When calling a Web API in Angular, is it safe to use Http Get with passwords included in the fields? Or would it be more secure to utilize Http Post instead? Check out this example on how to execute an Http.get request in Angular: http.get(baseUrl + &apo ...

Error: an empty value cannot be treated as an object in this context when evaluating the "businesses" property

An error is occurring stating: "TypeError: null is not an object (evaluating 'son['businesses']')". The issue arose when I added ['businesses'][1]['name'] to 'son' variable. Initially, there was no error wi ...

Unlocking the Power of $http and Stream Fusion

I'm interested in accessing the public stream of App.net. However, when I attempt to retrieve it using a simple $http.get(), I only receive one response. $http .get('https://alpha-api.app.net/stream/0/posts/stream/global') .success(func ...