Alert checkboxes do not show labels!

This is the code:

addValues(){
let alert = this.alertCtrl.create();
alert.setTitle('List of Courses');

this.schoolAppUsers.loadAllCourses().subscribe(response => {
  for (let entry of response)
  {
    alert.addInput({
      type: 'checkbox',
      label: entry.CourseName,
      value: entry.CourseID.toString()
      
    });
  }
})
alert.addButton('Cancel');
alert.addButton({
  text: 'Okay',
  handler: data => {
    console.log('Checkbox data:', data);
    this.testCheckboxOpen = false;
    this.testCheckboxResult = data;
  }
});
alert.present().then(() => {
  this.testCheckboxOpen = true;
});

}

The alert shows only the checkboxes but there are no labels for them

      label: entry.CourseName,

Also

    console.log('Checkbox data:', data);

only return the last value in the array:

  undefined: "17"

the handler supposed to return the selected options:

 0: "1"
 1: "5"

and so on… can someone help plz

Does your Observable emit an array of all school courses? If not, I don’t understand why you are for’ing over a single response. If so, isn’t that fragile? How do administrators add or delete courses?

Seocnd topic: I’d be cautious about binding an alert to an Observable like that, because the alert presents in the synchronous world, while the Observerable emits in the asynchronous world. So you may see an alert that has only half the courses, for example.

I’ve handled a similar situation by creating a Form, then adding checkbox and other controls to the Form using addControl inside .subscribe(…) and using *ngFor in the template.

   this.schoolAppUsers.loadAllCourses().subscribe(response => {
                         console.log(response);
          }

emits all the courses: [ Object, Object,…]

               Array[3]
               0: object
               1: object
               2: object

and

       for (let entry of response)
          {
          console.log(entry.CourseName);   // Lists all  courses names
            alert.addInput({
            type: 'checkbox',
            label: entry.CourseName,
            value: entry.CourseName
      
          });
         }

each object got : CourseID and CourseName
and if so you are saying that binding here is not recommended. how do I handle this issue, can you write a sample code for it : should I use ion-select for it ?? Im kinda confused in how to work that out.

Also , what does addControl do ? can you please clarify about it , much appreciated , thank you
and about how administrator add courses… im making this alert for administrator only… the button that calls this Alert function is a button in an action sheet thats *ngIf for admin only

But it emits them over time, right? How do you know that you are creating the alert after every single one has been emitted? Unless it’s emitting Object[] Object[] Object[]? But it isn’t, I don’t think.

If you build a Form, then the page will keep showing more courses as they are emitted, unlike the alert, which only has the options you created for it before you called alert.present().

addControl() adds a FormControl to the Form. You could use it, for example, to add a checkbox control each time a course is emitted.

I’m not comfortable posting code, because I don’t fully understand what you’re trying to accomplish. Are there only four courses, so the size of an alert makes sense? Or are there 400 courses? I guess I don’t understand why you’re using an alert at all.

Please check this. it might make more sense

Mr.Aaron

can you please show an example of the form and how to add checkbox each time a course is emitted !
or perhaps a link to explain how I can accomplish this. thanx bro

@yasirpanjsheri I don’t think that code will work because the subscribe event is called asynchronously, so the alert is already presented (and I don’t think adding inputs to the alert after that will work properly, at least I don’t think that Ionic2 alerts supports this behaviour).

If the subscribe event is called just once, you could turn it into a promise and call the alert in the promise, after the courses are loaded:

addValues(): Promise<any> {
	return this.schoolAppUsers.loadAllCourses().toPromise().then(response => {
		let alert = this.alertCtrl.create();
		alert.setTitle('List of Courses');
		
		for (let entry of response) {
			alert.addInput({
				type: 'checkbox',
				label: entry.CourseName,
				value: entry.CourseID.toString()
			});
		}
		
		alert.addButton('Cancel');
		alert.addButton({
			text: 'Okay',
			handler: data => {
				console.log('Checkbox data:', data);
				this.testCheckboxOpen = false;
				this.testCheckboxResult = data;
			}
		});

		return alert.present().then(() => {
			this.testCheckboxOpen = true;
		});
	})
}
1 Like

You’re assuming the Observable completes, which it may or may not, depending where the course info is being read from. More importantly, it might be a design flaw for the Observable to complete. Example: Users A and B open the program. User A modifies course C. User B modifies course C. To deal with that full-on, you’d need transactional memory or something similar. But you can sidestep some of the worst cases with a dynamic form.

1 Like

@AaronSterling I don’t know if that reply is to me, but anyway in my code I did it this way because I think Ionic2 Alerts are defined statically and observing several events wouldn’t work with the Alert. I suppose the this.schoolAppUsers.loadAllCourses() returns the response just once (so a promise is fine in this case, and if an error occurs he can handle just like with an observer).

On the other hand, if this.schoolAppUsers.loadAllCourses() can receive more events (listening to changes in the server, for example), a promise would not be suitable, and he should not use an alert, but put the checkboxes in the component HTML or in a custom modal (using an async pipe, or something like that).