2

I am working on Angular app. I imported jQuery package using following code.

$ npm install jquery --save

I am trying to transfer my .js data of html web page to app.component.ts of angular. My setup for JQuery is done in angular app and I even tested it. I am having checkbox in my web page, which will be selected to remove file using button click. To achieve this, I used the following code in JS.

function RemoveFile() {
  var files = document.getElementById("files").children;
  for (var i = 1; i < files.length; i++) {
    if (files[i].children[0].children[0].checked) {
      files[i].remove();
      i--;
    }
  }
}

It is working fine in normal html page but when I used it in app.component.ts. It is giving me the following

Property 'checked' does not exist on type 'Element'

How can I rectify it or used something like this?

selectedFile.children[4].children[0].checked = $(this)[0].checked;
2
  • jQuery should not be used for DOM manipulation. Angular is amazingly good at building HTML from your model - why would you go and interfere with it by using jQuery? Commented Mar 5, 2020 at 6:52
  • could you post html code as well here. have used [(ngModel)]="check" on checkbox type input ? Commented Mar 5, 2020 at 7:09

2 Answers 2

2

jQuery should only be used in Angular in the most exceptional of cases. Angular is a javascript framework for managing the DOM dynamically based on your model. If you manage the DOM outside of Angular you will more than likely suffer unexpected results.

In your case, I'm going to assume you've got some array of files in your component.

component.ts

export class MyComponent {
  files: any[] = [];

  ngOnInit() {
    // somehow get the files
    this.files = [];
  }
}

And I'm going to assume that in your HTML you've built some kind of list containing a nested checkbox for each file.

The user will check some checkboxes, and then press a button to remove those files from the list (and probably perform some other action).

component.html

<div id="files">
  <div *ngFor="let file of files">
    <input type="checkbox" />
  </div>
</div>
<button (click)="RemoveFile()">Remove files</button>

So you have used Angular to build the list, but now you want to use jQuery to "unbuild" the list? Why would you do that?

The power of Angular is in its simplicity - the HTML will reflect whatever's in your files array. So if you want to "unbuild" your list, then simply remove items from the array.

Admittedly, it's a little trickier when you have to consider things like an array of checkboxes, but that's no excuse to resort to using jQuery.

Since you are effectively going to build a form with a dynamic array, the best way to do handle this would be to use a reactive form with a form array.

Import the reactive forms module in your app module:

app.module.ts

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

@NgModule({
  imports: [
    FormsModule,
    ReactiveFormsModule 
  ]
}

In your component you will need to inject FormBuilder from @angular/forms. Then build a form once you have your model (which might be inside a service subscription).

You will then delete the files in the form's submit handler. You do have to splice two arrays, but the form array is built from the files array, so they have matching indexes.

component.ts

import { FormBuilder, FormGroup, FormArray } from '@angular/forms';
// ... other imports

export class MyComponent {

  constructor(private formBuilder: FormBuilder) {}

  files: any[] = [];
  form: FormGroup;

  private filesFormArray: FormArray;

  ngOnInit(): void {
    // somehow get the files
    this.files = [];

    // Build an array of form groups if you want each file to have multiple controls.
    // Build an array of form controls if you want each file to have a single control
    // I will just add one control per file - an unchecked checkbox,
    // but use a form group per file to show how it is done

    const filesFormGroups = this.files.map(x => this.formBuilder.group({
      delete: this.formBuilder.control(false)
    }));

    // Build the form array. Store a reference to it for easy access later
    this.filesFormArray = this.formBuilder.array(filesFormGroups);

    // Build the whole form. At the moment there will only be files.
    this.form = this.formBuilder.group({
      files: this.filesFormArray
    });
  }

  onSubmit(): void {
    // start at the end of the array and work backwards
    for (let i = this.files.length - 1; i >= 0; i--) {
      // get the checkbox from the form array
      const checkBox = this.filesFormArray.controls[i].get('delete') as FormControl;
      if (checkbox.value) {
        // remove the item from the model and the form
        this.files.splice(i, 1);
        this.filesFormArray.controls.splice(i, 1);
      }
    }
  }
}

In your HTML, you still build from your files, but also bind to the form. You use the directives formGroupName, formArrayName, and formControlName to match the structure of the form group you built in your component.

component.html

<form [formGroup]="form" (submit)="onSubmit()">
  <div formArrayName="files">
    <div *ngFor="let file of files; let i = index" [formGroupName]="i">
      <input type="checkbox" formControlName="delete" />
    </div>
  </div>
  <button>Remove files</button>
</form>
Sign up to request clarification or add additional context in comments.

Comments

0

// First install jQuery npm install --save jquery

// and jQuery Definition npm install -D @types/jquery

add jquery path in angular.json script: [] array under build like

script: [ "node_modules/jquery/dist/jquery.min.js"]

then add declare var $:any; after import statement and jquery ready to use

5 Comments

I tried your given steps but they did not work. I am getting the same error.
How can I access children[] or parent[] element of the given element?
Please don't encourage the use of jQuery in Angular like this. Angular should be used for DOM manipulation, not jQuery.
@Kurt Hamilton I won't but still i am in middle way to complete my project. I need to know how to do it?
@AbhiSingh The answer is... don't. Please learn how to use Angular

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.