The data from the server doesn t appear in the UI

When the page loads i am trying to fetch data from the JSON server which should then appear in the UI, however the data doesn t show.I am using materialize css as a css framework.
This is a link to my Github repo:

Please type in npm run dev in the terminal to start the app.

Hello and welcome to the forum :partying_face:!

You’re calling a function before it’s defined:

document.addEventListener("DOMContentLoaded", getContacts);

const getContacts = () => {
  axios
    .get("http://localhost:3000/contacts")
    .then(data => ui.showContacts(data))
    .catch(err => console.log(err));
};

There’s another error too, but I’ll let you find out by yourself :stuck_out_tongue:,

Happy coding!

Thanks for your help.
const getContacts = () => {

axios

.get("http://localhost:3000/contacts")

.then(data => ui.showContacts(data))

.catch(err => console.log(err));

};

document.addEventListener(“DOMContentLoaded”, getContacts);

I must be exceptionally stupid today but i still don t understand why forEach is not a function?
TypeError: “contacts.forEach is not a function”

what value type is contacts?

1 Like

You don’t know what the response object contains :slight_smile:.

You should read the axios docs or log the response object and explore it on the developer tools.

Thanks, i figured it out.
const getContacts = () => {

axios

.get("http://localhost:3000/contacts")

.then(data => ui.showContacts(data.data))

.catch(err => console.log(err));

};

1 Like

Here we go again.I want to be able to post data to json server when i click submit button on the form and that data should then appear in the UI.What am i doing wrong?

//Submit contact

const addContact = () => {
  const name = document.querySelector("#name");
  const email = document.querySelector("#email");
  const phone = document.querySelector("#phone");
  const type = document.querySelectorAll('input[name="type"]');
  const data = {
    name: name,
    email: email,
    phone: phone,
    type: type
  };

  axios
    .post("http://localhost:3000/contacts", data)
    .then(response => {
      ui.clearFields();
      getContacts();
    })
    .catch(err => console.log(err));
  e.preventDefault();
};

document.querySelector("#contact-form").addEventListener("submit", addContact);

Github repo:

The problem is that the e variable is not declared inside addContact, hence an error is thrown and the request is aborted :slight_smile:. Add the e variable to the function and it should work.

Thank you for your response.I added the event variable, however i am getting an empty object both in the console and the UI.I tried adding headers with content-type:application/json, but it still doesn t work.

//Submit contact

const addContact = e => {

  const name = document.querySelector("#name");

  const email = document.querySelector("#email");

  const phone = document.querySelector("#phone");

  const type = document.querySelectorAll('input[name="type"]');

  const data = {

    name: name,

    email: email,

    phone: phone,

    type: type

  };

  axios

    .post("http://localhost:3000/contacts", data)

    .then(response => {

      ui.clearFields();

      getContacts();

    })

    .catch(err => console.log(err));

  e.preventDefault();

};

document.querySelector("#contact-form").addEventListener("submit", addContact);

Yes, that’s right :slight_smile:.

I don’t want to give you the answer right away, so I’ll ask you to log the data variable to the console so you can see the contents and try to figure out what’s wrong.

A couple of other things:

  1. Whenever you reply to someone, please click on the reply button below the message you’re replying to or use @username on the comment, that way the user gets notified.
  2. When you post code, please put it inside back ticks.

The data wasn t adding to the json server or the UI because i didn t add .value when selecting input fields.It s working now.

const name = document.querySelector("#name").value;
const email = document.querySelector("#email").value;
const phone = document.querySelector("#phone").value;
const type = document.querySelector('input[name="type"]').value;

I was just wondering, as you can see i have two radio buttons as a part of my form, one with the value of personal which is always checked and the other with the value of profesional which is not.If i check profesional button and then submit a form how do i return it to it s checked value which is personal by default?My current solution isn t working.

//app.js
//Submit contact
const addContact = e => {

    const name = document.querySelector("#name").value;

    const email = document.querySelector("#email").value;

    const phone = document.querySelector("#phone").value;

    const type = document.querySelector('input[name="type"]').value;

    const data = {

        name: name,

        email: email,

        phone: phone,

        type: type

    };

    axios

        .post("http://localhost:3000/contacts", data)

        .then(response => {

            ui.clearFields();

            getContacts();

        })

        .catch(err => console.log(err));

    e.preventDefault();

};

document.querySelector("#contact-form").addEventListener("submit", addContact);
//ui.js
class UI {

    constructor() {

        this.contactList = document.querySelector("#contact-list");

        this.nameInput = document.querySelector("#name");

        this.emailInput = document.querySelector("#email");

        this.phoneInput = document.querySelector("#phone");

        this.radioInput = document.querySelector('input[name="type"]');

    }
    clearFields() {

        this.nameInput.value = "";

        this.emailInput.value = "";

        this.phoneInput.value = "";

        this.radioInput.checked = false;

    }

}
<!--html-->
<!--Radio buttons-->

            <p>

              <label>

                <input name="type" type="radio" value="personal" checked />

                <span>Personal</span>

              </label>

              <label>

                <input name="type" type="radio" value="profesional" />

                <span>Profesional</span>

              </label>

            </p>

You can just reset the form: document.querySelector('#form_id').reset(). You can see it working here: Resetting a form - JSFiddle - Code Playground

In regards to the formatting of the code, please use three back ticks when formatting multi-line code and single when the code is a single line, thanks :slight_smile:.

That was fantastic!Thank you so much.Will follow instructions when formatting the code.

1 Like

Editing issue
When i click on the edit button bellow any particular contact i want to be able to fill the form on the left with that contacts name, email, phone and type so that i can be able to update it with put request .Currently i am only able to transfer contact s name.I am unable to find an error.Also as a side note is there a shorter way of fetching that data because as you can see from the code in app.js i have to go through multiple sibling elements.
app.js

//Edit contact

const editContact = e => {
  if (e.target.parentElement.classList.contains("edit")) {
    const id = e.target.parentElement.dataset.id;
    const name =
      e.target.parentElement.parentElement.previousElementSibling
        .previousElementSibling.previousElementSibling.textContent;
    const type =
      e.target.parentElement.parentElement.previousElementSibling
        .previousElementSibling.previousElementSibling.children[0].textContent;
    const email =
      e.target.parentElement.parentElement.previousElementSibling
        .previousElementSibling.textContent;
    const phone =
      e.target.parentElement.parentElement.previousElementSibling.textContent;

    const data = {
      id: id,
      name: name,
      email: email,
      phone: phone,
      type: type
    };

    ui.fillForm(data);
  }
  e.preventDefault();
};

document.querySelector("#contact-list").addEventListener("click", editContact);

ui.js

class UI {
  constructor() {
    this.contactList = document.querySelector("#contact-list");
    this.nameInput = document.querySelector("#name");
    this.emailInput = document.querySelector("#email");
    this.phoneInput = document.querySelector("#phone");
    this.radioInput = document.querySelector('input[name="type"]');
    this.contactForm = document.querySelector("#contact-form");
  }
showContacts(contacts) {
    let output = "";

    contacts.forEach(contact => {
      output += `
      <divclass="row">
      <div class="col s12">
      <div class="card">
      <div class="card-content">
      <p class="card-title indigo-text text-darken-4">
      ${contact.name}
      <a class="waves-effect indigo darken-4 btn right">${contact.type}</a>
      </p>
      <p><i class="fas fa-envelope-open"></i> ${contact.email}</p>
      
      <p><i class="fas fa-phone"></i> ${contact.phone}</p>
      <br>
      <p>
      <a class="waves-effect grey darken-4 btn-flat edit" data-id="${contact.id}"><span class="white-text">Edit</span></a>
  <a class="waves-effect red darken-2 btn-flat delete" data-id="${contact.id}"><span class="white-text">Delete</span></a>
      </p>
      </div>
      </div>
      </div>
      </div>`;
    });
    this.contactList.innerHTML = output;
  }
fillForm(data) {
    this.nameInput.value = data.name;
    this.emailInput.value = data.email;
    this.phoneInput.value = data.phone;
    this.radioInput.value = data.type;
  }
}

export const ui = new UI();

I forgot to count <br> as a previous sibling element that s why it didn t work.

<p><i class="fas fa-phone"></i> ${contact.phone}</p>
      <br>
      <p>
      <a class="waves-effect grey darken-4 btn-flat edit" data-id="${contact.id}"><span class="white-text">Edit</span></a>
  <a class="waves-effect red darken-2 btn-flat delete" data-id="${contact.id}"><span class="white-text">Delete</span></a>
      </p>