1

I have added images from gallery/camera to an ion-slider view.I have an action sheet which gives me an option to add or remove the images from the slider view.Adding is working fine as i am adding that image to array and providing that updated array to the slider. But for removing an image i need to get the index of the image that is active on the slider and after that i need to remove it. I m not able to get the active index using this code :

onSlideChanged() {
     try{
      let currentIndex = this.slides.getActiveIndex();
      console.log("Current index is", currentIndex);
     }catch(e){
       console.log("not able to get the active index");
     }   }

this also goes into the catch part. Then i m removing the first element from the array and updating the array for slider.The array size is reduced when i press the delete button from action sheet but all the images in the slider disappears leaving a blank space.

<div *ngIf="field.value" (click)="takePicture(field.name)">
     <ion-slides pager="true" style="max-height:500px" (ionSlideDidChange)="onSlideChanged()">
     <ion-slide *ngFor="let c of field.value">
     <img class="image-attach" [src]="c" draggable="true">
     </ion-slide>
     </ion-slides>
      </div>
      <canvas #latlon style="display:none"></canvas>
    </div>

code for setting images to the slider

removePicture(name) {
    for (let i = 0; i < this.formType.template.secs.length; i++) {
      for (let d = 0; d < this.formType.template.secs[i].fields.length; d++) {

        if (this.formType.template.secs[i].fields[d].name == name) {

        if(this.formType.template.secs[i].fields[d].value.length>1)
        {
          this.formType.template.secs[i].fields[d].value.splice(this.currentIndex,1);
          this.attachedImagesArray.splice(this.currentIndex,1);
          console.log(this.formType.template.secs[i].fields[d].value.length);
          var arr = this.formType.template.secs[i].fields[d].value;
          console.log("^^^^^^^",arr);
          this.formType.template.secs[i].fields[d].value = this.formType.template.secs[i].fields[d].value;
        }
        else{
        console.log("*********",this.formType.template.secs[i].fields[d].value);
        this.formType.template.secs[i].fields[d].value = "";
        }
      }
    }
    }
  };

this is the code i m using for removing the images from slider. I m new to ionic so don't know why this is happening, i googled for it but nothing worked for me.

for putting the images to the slides i m using the following code :

selecPicture(name) {
    this.camera.getPicture({
      quality: 50,
      destinationType: this.camera.DestinationType.FILE_URI,
      targetHeight: 500,
      targetWidth: 500,
      encodingType: this.camera.EncodingType.JPEG,
      mediaType: this.camera.MediaType.PICTURE,
      sourceType: this.camera.PictureSourceType.PHOTOLIBRARY
    }).then((imageData) => {

      //alert(imageData);
      // imageData is a base64 encoded string DATA_URL FILE_URI 'lat: '+lat+', lon: '+lon,
      let base64Image = "data:image/jpeg;base64," + imageData;

      this.geolocation.getCurrentPosition().then((resp) => {
        let lat = resp.coords.latitude;
        let lon = resp.coords.longitude;
        this.lat = lat;
        this.lon = lon;
        let d = new Date();
        let draftSavedTime = d.toString().substr(4, 11);
        let canvas = this.canvasRef.nativeElement;
        let context = canvas.getContext('2d');
        console.log(context);
        console.log("hello");
        let newImg = new Image();
        newImg.src = imageData;
        newImg.onload = () => {

          canvas.setAttribute("width", newImg.height);
          canvas.setAttribute("height", newImg.width);
          // context.drawImage(newImg, 0, 0);
          context.drawImage(newImg, 0, 0, newImg.width, newImg.height);
          // context.font = "15px impact";
          context.font = "bold 13px Arial";
          // context.textAlign = 'center';
          context.fillStyle = 'red';
          context.fillText(draftSavedTime, 20, 20);
          // context.fillText('Lat: '+lat+'     Lon: '+lon, canvas.width / 2, canvas.height * 0.9);
          context.fillText('Lat: ' + lat, canvas.width * 0.1, canvas.height * 0.8);
          context.fillText('Lon: ' + lon, canvas.width * 0.1, canvas.height * 0.9);
          // context.fillText('Lon: '+lon, canvas.width / 2, canvas.height * 0.8);
          let image = canvas.toDataURL();
          this.attachedImages.push(image);
          this.setValue(name, image);

    };
      }).catch((error) => {
        console.log('Error getting location', error);
      });
    }, (err) => {
      console.log(err);
    });
  }

to set the value of image in the field : //to set the value in the field

setValue(name, data) {

    console.log(this.attachedImages);
    console.log(this.formType.template.secs); //3
    for (let i = 0; i < this.formType.template.secs.length; i++) {
      console.log(this.formType.template.secs[i].fields); //2
      for (let d = 0; d < this.formType.template.secs[i].fields.length; d++) {
        if (this.formType.template.secs[i].fields[d].name == name) {

          this.attachedImagesArray.push({
            name : this.formType.template.secs[i].fields[d].name,
            image : data,
            number : d
          });


var group_to_values = this.attachedImagesArray.reduce(function (obj, item) {
    obj[item.name] = obj[item.name] || [];
    obj[item.name].push(item.image);
    return obj;
}, {});

var imageGroup = Object.keys(group_to_values).map(function (key) {
    return {key: key, image: group_to_values[key]};
});

var pre = document.createElement("pre");
pre.innerHTML = "imageGroup:\n\n" + JSON.stringify(imageGroup, null, 4);
document.body.appendChild(pre);


var newArr = [];
newArr.push({imageGroup});

for(var item in newArr)
{
  console.log(newArr[item]);
  for(var sec in newArr[item])
  {
    console.log(newArr[item][sec]);
  }

  for( var elm in newArr[item][sec])
  {
    console.log(newArr[item][sec][elm]);
  }

  for( var key in newArr[item][sec][elm])
  {
    this.arrNameStr = newArr[item][sec][elm].key;
    console.log(newArr[item][sec][elm].image);
  }
}

console.log(this.arrNameStr);
if(this.arrNameStr.includes(this.formType.template.secs[i].fields[d].name))
{
  console.log(newArr[item][sec][elm].image);
  console.log(this.formType.template.secs[i].fields[d].value);
  this.formType.template.secs[i].fields[d].value = newArr[item][sec][elm].image;
  console.log(this.formType.template.secs[i].fields[d].value);
}
  }
}
  }
};
puja
  • 87
  • 11
  • Hey, can you show how exactly you are referencing slides ui element and assigning that to your "slides" variable? Also please console.log(this.slides). I think I know what is going on here but I want to make sure. – Sergey Rudenko Jun 12 '18 at 02:49

1 Answers1

0

First ensure that you get this event firing off and that your reference to the slides element in the template returns the Slides: (ionSlideDidChange). Do:

onSlideChanged() {
    console.log(this.slides)
}

Your console should return reference to the slides element.

It is unclear how you obtain this reference based on your code, but seeing you have *ngIf directive there is a chance you are not actually able to get it since the element doesn't exist at init stage of the component.

To fix that you can pass reference to ion-slides in the ionSlidesChanged method:

<div *ngIf="field.value" (click)="takePicture(field.name)">
     <ion-slides #mySlides (ionSlideDidChange)="onSlideChanged(mySlides); mySlides.update()" pager="true" style="max-height:500px">
         <ion-slide *ngFor="let c of field.value">
             <img class="image-attach" [src]="c" draggable="true">
         </ion-slide>
     </ion-slides>
 </div>

Now in the actual method you should be able to get the value of currentIndex:

onSlideChanged(mySlides) {
    let currentIndex = mySlides..getActiveIndex();
    // here do splice or whatever manipulation you need with your data source / array
}

Let me know if this helped.

UPDATE: since there is a need to refresh slides UI after the change to the model it is good to call "update" method: (ionSlideDidChange)="onSlideChanged(mySlides); mySlides.update()".

Template is now updated with this.

Sergey Rudenko
  • 8,809
  • 2
  • 24
  • 51
  • in the console of this.slides, i m getting undefined – puja Jun 12 '18 at 03:29
  • cool then try following my answer. You should get reference to Slides and get active index easily. – Sergey Rudenko Jun 12 '18 at 03:30
  • i tried it .. but i m getting : TypeError: undefined is not an object (evaluating 'mySlides.getActiveIndex') in the console log of current index – puja Jun 12 '18 at 03:41
  • also i have created a reference in ts file : @ViewChild('slides') slides; – puja Jun 12 '18 at 03:43
  • Your ViewChild wont create reference due to *ngIf. You need to add id to slides (#mySlides) then pass it exactly as in my code. – Sergey Rudenko Jun 12 '18 at 03:50
  • yes i added #mySlides,
    – puja Jun 12 '18 at 03:55
  • so you see you are missing mySlides as argument! It should be onSlideChanged(mySlides). This way you pass reference. – Sergey Rudenko Jun 12 '18 at 03:56
  • in ts file : onSlideChanged(mySlides) { console.log("this.slide value:",this.slides); let currentIndex = mySlides.getActiveIndex(); console.log("index of active slide",currentIndex); }, but now i m getting some value of this.slides – puja Jun 12 '18 at 03:58
  • oh ya i missed that..i m getting active index now. when i put active index in the delete part , like this.formType.template.secs[i].fields[d].value.splice(currentIndex,1); after making currentIndex public , still the array count gets decreased but the image goes blank – puja Jun 12 '18 at 04:03
  • hehe. Good just copy with pride and be careful with details. Your removeImage method is pretty dodgy. So after "deletion" ideally you should also call update() on the slides reference. if you add your updated code I can show how. – Sergey Rudenko Jun 12 '18 at 04:06
  • this.formType.template.secs[i].fields[d].value.splice(this.currentIndex,1); this.attachedImagesArray.splice(this.currentIndex,1); in this the items from array are deleted in the right order according to the currentIndex value, but most of the time the images goes blank, just showing the pager marker and pager keeps on changing when deleting the items even when images are not visible. – puja Jun 12 '18 at 04:14
  • OK to fix that I will post a solution. – Sergey Rudenko Jun 12 '18 at 04:20
  • when i use this.slides.update(); function , i get an error : TypeError: undefined is not an object (evaluating 'this.slides.update') – puja Jun 12 '18 at 04:24
  • see what I have just added to the template code -> ion-slides: (ionSlideDidChange)="onSlideChanged(mySlides); mySlides.update()". Try this approach. A long as your removePicture is synchronous method - this will call an update after the onSlideChanged handler. – Sergey Rudenko Jun 12 '18 at 04:26
  • Thanks a ton..!! It worked for me. I was using this.slides.update in the removeImage method, maybe thats why it was not working. – puja Jun 12 '18 at 04:41
  • Yes your this.slides is not referencing anything because at component initialization time it is most likely not rendered thanks to *ngIf. So whenever you have conditional element in your template in most cases you will have to pass reference to it using a method. Cheers – Sergey Rudenko Jun 12 '18 at 04:43
  • but sometimes again i m facing the same issue of getting the image blank when i press the remove image button. – puja Jun 12 '18 at 04:44
  • Are you sure this is a blank slide? can it be the background of slides element? Sometimes when you remove a slide - slides won't auto move you to a nearest slide. So you might think how to address that as well. I normally force slides to move to index 0. – Sergey Rudenko Jun 12 '18 at 05:24
  • okay.This might be the reason but on sliding as well i can't see any other image as well.Let me also try to force it to index 0. – puja Jun 12 '18 at 05:45