0

enter image description here

I want to set an ion-toggle according to the value that exists on the db table.

If the value is stored in the table the toggle should be ON, if not OFF. Off (left) On(right)

So, if the artist column in artists_interests table there is a value of Cinematographer then i want the <ion-toggle [(ngModel)]="artistInterests.Cinematographers" (click)="artistInterest(artists, 'Cinematographers')"> to be ON

enter image description here

here is what I have so far.

html

    <ion-item>
      <ion-label>Cinematographers</ion-label>
      <ion-toggle color="success" [(ngModel)]="artistInterests.Cinematographers" (click)="artistInterest(artists, 'Cinematographers')"></ion-toggle>
    </ion-item>

    <ion-item>
      <ion-label>Graphic Designers</ion-label>
      <ion-toggle color="gold-white" [(ngModel)]="artistInterests.graphicDesigners" (click)="artistInterest(artists, 'Graphic Designers')"></ion-toggle>
    </ion-item>

.ts to call the API function to store value (e.g. Graphic Designers) on DB table - that work I mean it stores 'Graphic Designers' in the artist column in DB table.

artistInterest(artists:string, messageTitle: string)
{
    this.userData.artistSettings(this.userDetails.uid, messageTitle).pipe(
      map((data: any) => {
        if (data.success) {
          Swal.fire({
            icon: 'success',
            title: messageTitle,
            showConfirmButton: false,
            backdrop: false,
            timer: 2500
          })
        }
      })
    ).subscribe()
  }

.ts function to retrieve the data from api function with

export class CreativeSettingsPage implements OnInit {
  creativeInterests: any= {};
  creative: any= {};
  artistInterests: any= {};
  artists: any= {};
  userDetails: any = {};
  constructor(
    public userData: UserData
  ) {
    this.userDetails = this.userData.getUserData();
    this.creativeInsterestSet();
    this.artistsInsterestSet;
   }

ngOnInit() {
    this.artistsInsterestSet()
  }

artistsInsterestSet() {
this.userData.artistsInterests(this.userDetails.uid).pipe(
      map((data: any) => {
          if (data.success) {
              this.artistInterests = data.artistInterests;
              console.log( this.artistInterests);
          }
      })
  ).subscribe()
}

userData.ts

  artistsInterests(uid:number) {
    const url = this.appData.getApiUrl() + 'getArtistInterests';
    const data = this.jsonToURLEncoded({
        uid: uid
    });
    return this.http.post(url, data, { headers: this.options });
}

php function getArtistInterests

function getArtistInterests()
{
    $request = \Slim\Slim::getInstance()->request();
    $data = json_decode($request->getBody());
    $response['success'] = true; // 1

     $uid = $request->post('uid');

    $db = getDB();
    $sql = "SELECT A.artist, U.profile_pic,U.first_name,U.last_name,
    DATE_FORMAT(A.created, '%W %D %M %Y, %l %i %p') as date
    FROM  artists_interests A 
    LEFT JOIN users U ON A.uid_fk=U.uid 
    WHERE A.uid_fk=? GROUP BY A.artist";
    $stmt = $db->prepare($sql);
    $stmt->execute(array($uid));

    $db = null;
    $artistInterests = $stmt->fetchAll(PDO::FETCH_OBJ);

    foreach ($artistInterests as $feed) {
        $feed->profile_pic = SITE_URL . 'usersPic/' . $feed->profile_pic;
    }

    $data['success'] = true;
    $data['artistInterests'] = $artistInterests;
    echo json_encode($data);
}

the value is stored as e.g. Graphic Designer (two words) in artists_interests table so [(ngModel)]="artistInterests.graphicDesigners" will not work. But it should work for [(ngModel)]="artistInterests.Cinematographers" as far as I know. By working I mean the toogle to be ON (right on slide)

Pella Post
  • 99
  • 9

1 Answers1

0

A ion-toogle using ng-model only get two values "true" or "false" (it's like a input type checkbox). If you want to "transform" the true/false to on/off you can use some like

<ion-toogle [ngModel]="artistInterests.Cinematographers=='ON'?true:false"
            (ngModelChange)=artistInteres.Cinematographers=$event?'ON':'OFF'>

NOTE: if you use [(ngModel)] (or in reactiveForms use formControlName, try to avoid use [checked] or [value] or another property.

NOTE2: When we use a ion-toogle or another component that use [(ngModel)] (can be a component in material or in ng-bootstrap) it's util use [(ngModel)]="value and {{value|json}} in .html to know really what value return

Update I finally think that I understand your problem. I imagine you has two tables:

artist_interest=[{uid_fk:..,artist:...,created:...}...]
//and
users=[{uid:..,profile_pic:...,first_name:...,last_name:...}]

And in a call you get some like

[{artist:"Painters",date:"Friday 21 January 2022,1 08 PM",firstName:"test",lastName:"User",uid:1122},
    {artist:"Graphic Designers",date:"Monday 24 January 2022,1 08 PM",firstName:"test",lastName:"User",uid:1122}]

You want to show the data and when change delete the elements in "artist_interest" you get off and add the elements in "artist_interest" you get on

Futhermore you has an array of "cathegories"

You can take two aproach:

  1. Each change in ion delete/add to the dbs
  2. To have a button and make an unique call to delte/add the new elements

If you take the first aproach you only need a function to know if the category is in the array

  isInInterest(cathegory:string)
  {
    return this.artistInterests.find(x=>x.artist==cathegory)?true:false
  }

And you has some like

  <ion-row *ngFor="let cathegory of cathegories;let i=index">
    <ion-item>
      <ion-label>{{cathegory}}</ion-label>
      <ion-toggle [ngModel]="isInInterest(cathegory)"
                  (ngModelChange)="change($event,cathegory)"
        color="success"
      ></ion-toggle>
    </ion-item>
  </ion-row>

where you has some like

  change(checked:boolean,cathegory:string)
  {
    if (checked)
    { 
        this.service.add(cathegory).subscribe(res=>{
          this.artistInterests.push(res)
        })
    }
    else
    {
      this.service.remove(cathegory).subscribe(res=>{
        if (res.success==true)
        {
          this.artistInterests=this.artistInterests.filter(x=>x.artist!=cathegory)
        }
      })
    }
  }

See how, we subscribe to the method of our service "add" and "remove", and then we need manually add/remove the elements of our array.

For the second method we are using an auxiliar array of objects created using "map" and the list of cathegories.

After get the artist -in the subscribe we create our array

this.cathegoriesValues=this.cathegories.map(x=>{
  const isInInterest=this.artistInterests.find(a=>a.artist==x)?true:false
  return {
    cathegory:x,oldValue:isInInterest,newValue:isInInterest}
})

And we use some like

  <ion-row *ngFor="let cathegory of cathegoriesValues;let i=index">
    <ion-item>
      <ion-label>{{cathegory.cathegory}}</ion-label>
      <ion-toggle [(ngModel)]="cathegory.newValue" color="success"></ion-toggle>
    </ion-item>
  </ion-row>

Just only, in the button, we filter the data that newValue and oldValue are different and call to our service to remove/add the data to our dbs

submit()
{
   const data=this.cathegoriesValues.filter(x=>x.newValue!=x.oldValue)
   this.serviceUpdateDbs(this.artistInterests.uii,data)
}

NOTE: I created a little and incomplete stackblitz here

Eliseo
  • 50,109
  • 4
  • 29
  • 67
  • no i don't want to use it as ON or OFF. By on or off i meant IF THE VALUE EXISTS ON DB THEN TO BE RIGHT AS TRUE – Pella Post Jan 23 '22 at 20:02
  • my bad, sorry! really I don't know about your code or if you has a list of interest. Some time ago I wrote this [SO](https://stackoverflow.com/questions/63797930/get-multiple-checkbox-value-as-an-array-in-angular/63799360#63799360) to use a series of checkbox to manage an array. I don't know if can help you – Eliseo Jan 23 '22 at 20:47
  • i just want the toggle to be on the right side if there is a value of artistInterest is Cinematographers. What makes a toggle to be true or false? – Pella Post Jan 23 '22 at 21:05
  • @PellaPost, I update my old answer, I hope can help you – Eliseo Jan 24 '22 at 22:01