Error on Sortting Items is not a function

45 views Asked by At

I have a problem with my code

So, there is picture with like, when i click on the heart that add a like enter image description here there is a container down ma page and then the likes are also displayed in it. enter image description here

(picture to show you a context)

The problem is everything work fine, but when you use my function "filter" the likes are working on the photos but not down the page and that return me an error i don't really understand from where that come.

So can you help me please ?

import showMethods from "../factories/showMethods.js";
import lightbox from "../factories/lightbox.js";
import formularSecur from "../factories/formularSecur.js";

export default class OnePhotographer {
  constructor() {
    this.photographer = null;
    this.medias = [];
    this.likes = 0;
    this.lightbox = lightbox;
    this.indexLightbox = 0;
    this.getPhotographer();
    this.eInit();
  }

  eInit() {
    document.getElementById("filtre").addEventListener("change", (e) => {
      this.filter(e.target.value);
    });

    document.getElementById("filtre").addEventListener("click", (e) => {
      this.filter(e.target.value);
    });

    document.getElementById("contactForm").addEventListener("submit", (e) => {
      e.preventDefault();
      formularSecur.checkForm(this);
      document.getElementById("contactForm").reset();
    });

    this.lightbox.init(this);

    document.getElementById("closeLightbox").addEventListener("click", () => {
      this.lightbox.closeLightbox();
    });

    document.getElementById("prevBox").addEventListener("click", () => {
      this.lightbox.navLightbox("prev");
    });

    document.getElementById("nextBox").addEventListener("click", () => {
      this.lightbox.navLightbox("next");
    });

    document.addEventListener("keydown", (event) => {
      if (event.code == "ArrowLeft") {
        this.lightbox.navLightbox("prev");
      } else if (event.code == "ArrowRight") {
        this.lightbox.navLightbox("next");
      } else if (event.code == "Escape") {
        this.lightbox.closeLightbox();
      }
    });
  }

  filter(param) {
    if (param === "popular") {
      this.medias = this.medias.sort(this.order(param));
    } else {
      this.medias = this.medias.sort(this.order(param)).reverse();
    }
    document.querySelector(".containerMedias").innerHTML = "";
    this.medias.forEach((media, index) => {
      showMethods.showMedia(media, index);
      showMethods.showLikes(this, instance);
    });
  }


  order(settings) {
    return function (x, y) {
      if (x[settings] < y[settings]) {
        return -1;
      }
      if (x[settings] > y[settings]) {
        return 1;
      }
      return 0;
    };
  }

  setMedias(media) {
    this.medias = media;
  }

  async getPhotographer() {
    const response = await fetch("./data/photographers.json");
    const res = await response.json();
    const id = this.idUrlCatch();
    res.photographers.forEach((photographer) => {
      if (photographer.id == id) {
        this.photographer = photographer;
        res.media.forEach((media) => {
          if (media.photographerId == this.photographer.id) {
            this.medias.push(media);
            this.likes += media.likes;
          }
        });
        this.medias = this.medias.sort(this.order("popular"));
      }
    });
    showMethods.showData(this);
    showMethods.showLikes(this, instance);
  }

  idUrlCatch() {
    const str = window.location.href;
    const url = new URL(str);
    if (url.searchParams.get("id")) {
      const id = url.searchParams.get("id");
      return id;
    }
  }

  showData() {
    showMethods.showData(this);
    showMethods.showLikes(this, instance);
  }

  showHeader() {
    showMethods.showHeader(this);
  }

  showMedia(media, index) {
    showMethods.showMedia(media, index, this);
  }

  showLikes() {
    showMethods.showLikes(this, instance);
  }

  setSrcLightbox() {
    showMethods.setSrcLightbox(this);
  }

  closeLightbox() {
    showMethods.closeLightbox(this);
  }

  navLightbox() {
  }
}

this is the second part of my code

import lightbox from "../factories/lightbox.js";

export default {
  showData: function (instance) {
    this.showHeader(instance);
    instance.medias.forEach((media, index) => {
      this.showMedia(media, index, instance);
    });
    instance.showLikes();
  },

  showHeader: function (instance) {
    const infoHeader = document.querySelector(".photograph-header .containerInfo");
    const title = document.createElement("h1");
    title.textContent = instance.photographer.name;
    const loc = document.createElement("h3");
    loc.textContent = `${instance.photographer.city}, ${instance.photographer.country}`;
    const tagline = document.createElement("span");
    tagline.textContent = instance.photographer.tagline;
    infoHeader.appendChild(title);
    infoHeader.appendChild(loc);

    const headerImg = document.querySelector(
      ".photograph-header .containerImg"
    );

    const pic = `assets/photographers/${instance.photographer.portrait}`;
    const img = document.createElement("img");
    img.setAttribute("src", pic);
    img.setAttribute("alt", instance.photographer.name);

    headerImg.appendChild(img);
  },

  showMedia: function (media, index, instance) {
    const mediaSection = document.querySelector(".containerMedias");
    const card = document.createElement("div");
    card.classList.add("cardMedia");

    const containerImg = document.createElement("div");
    containerImg.classList.add("containerImg");
    if (media.image) {
      const mediaUrl = `assets/medias/${media.image}`;
      const mediaItem = document.createElement("img");
      mediaItem.dataset.index = index;
      mediaItem.setAttribute("tabindex", 0);

      mediaItem.addEventListener("click", (e) => {
        lightbox.showLightbox(e, instance);
      });
      mediaItem.addEventListener("focus", () => {
        mediaItem.addEventListener("keydown", (e) => {
          if (e.code == "Enter") {
            lightbox.showLightbox(e, instance);
          }
        });
      });

      mediaItem.setAttribute("src", mediaUrl);
      mediaItem.setAttribute("alt", media.title);
      containerImg.appendChild(mediaItem);
    } else {
      const mediaUrl = `assets/medias/${media.video}`;
      const mediaItem = document.createElement("video");
      mediaItem.dataset.index = index;
      mediaItem.controls = true;
      mediaItem.classList.add("media");

      mediaItem.addEventListener("click", (e) => {
        lightbox.showLightbox(e, instance);
      });

      mediaItem.setAttribute("src", mediaUrl);
      mediaItem.setAttribute("alt", media.title);
      mediaItem.setAttribute("data-index", index);
      containerImg.appendChild(mediaItem);
    }

    const subContain = document.createElement("div");
    subContain.classList.add("subContain");

    const picTitle = document.createElement("h3");
    picTitle.textContent = media.title;

    const like = document.createElement("span");

    like.setAttribute("tabindex", 0);
    like.classList.add("like");
    like.innerHTML = `${media.likes} <i class="fa-regular fa-heart"></i>`;
    like.addEventListener("click", () => {
      like.classList.toggle("active");
      if (like.classList.contains("active")) {
        media.likes += 1;
        instance.likes += 1;
        like.innerHTML = `${media.likes} <i class="fa-solid fa-heart"></i>`;
      } else {
        media.likes -= 1;
        instance.likes -= 1;
        like.innerHTML = `${media.likes} <i class="fa-regular fa-heart"></i>`;
      }
      instance.showLikes();
    });

    like.addEventListener("focus", () => {
      like.addEventListener("keydown", (event) => {
        if (event.code == "Enter") {
          like.classList.toggle("active");
          if (like.classList.contains("active")) {
            media.likes += 1;
            instance.likes += 1;
            like.innerHTML = `${media.likes} <i class="fa-solid fa-heart"></i>`;
          } else {
            media.likes -= 1;
            instance.likes -= 1;
            like.innerHTML = `${media.likes} <i class="fa-regular fa-heart"></i>`;
          }
          instance.showLikes();
        }
      });
    });

    subContain.appendChild(picTitle);
    subContain.appendChild(like);

    card.appendChild(containerImg);
    card.appendChild(subContain);

    mediaSection.appendChild(card);
  },

  showLikes: function (instance) {
    const priceContainer = document.createElement("div");
    priceContainer.classList.add("priceContainer");

    const likes = document.createElement("span");
    likes.classList.add("likes");
    likes.innerHTML = `<i class="fa-solid fa-heart"></i> ${instance.likes}`;

    const priceDay = document.createElement("span");
    priceDay.classList.add("priceDay");
    priceDay.innerHTML = `<i class="fa-solid fa-dollar-sign"></i> ${instance.photographer.price}`;

    priceContainer.appendChild(likes);
    priceContainer.appendChild(priceDay);

    document.querySelector(".photograph-header").appendChild(priceContainer);
  },
 
};

i don't really get why with my function showMedia everithing is fine, but with showLikes not

the code error

Uncaught TypeError: instance.showLikes is not a function
    at HTMLSpanElement.<anonymous> (showMethods.js:101:16)
(anonyme) @ showMethods.js:101

if you help me that will save my life Thank you for your time <3

1

There are 1 answers

0
Stephen Warren On

So i find why the bug is happening when i use my "filter" Function. I lose Instance on "showLikes" Function, so i don't have accès to the current instance.

One of my solution make my code in the onePhotograph.js, so no Instance ==> No bug.

I know this is maybe not the only solution, and maybe not the best. But this is a great solution also !

Best Regards