Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript Posting Data with fetch()

Updating UI elements (output of posted comment), need an example

Hi, just need an example of how posted comment will be rendered on actual page, how UI elements are updated with new comments from server. Video needed a little bit of an extension.

1 Answer

In the project files they start with this app.js, which already does that.

I have put some comments in there

you can see a trend, as they define constant for the elements you want to change, and then you change the innerHTML or other attributes of the elements to update with the fetched data, after the data was fetched.

const select = document.getElementById('breeds'); // this saves the dropdown menu element as a constant
const card = document.querySelector('.card');  // this saves the elment (div in this case) with class card as a constant
const form = document.querySelector('form'); 

// ------------------------------------------
//  FETCH FUNCTIONS
// ------------------------------------------

function fetchData(url) {
  return fetch(url)
    .then(checkStatus)
    .then( res => res.json() )
    .catch( err => console.error('Looks like there was a problem', err))
}

// this waits for both of the fetches to be complete, and 
Promise.all([
  fetchData('https://dog.ceo/api/breeds/list'), 
  fetchData('https://dog.ceo/api/breeds/image/random')
])
  .then( data => { // when the data is there, call these functions with the data as an argument
    generateOptions(data[0].message) 
    generateImage(data[1].message)
  })


// ------------------------------------------
//  HELPER FUNCTIONS
// ------------------------------------------

function checkStatus(response) {
  if(response.ok){
    return Promise.resolve(response);
  } else {
    return Promise.reject( new Error(response.statusText) );
  }
}

function generateOptions(data) {
  const options = data.map(item => `
    <option value='${item}'>${item}</option>
  `).join('');
  select.innerHTML = options; // set the innerHTML of the dropdown to options, which contain fetched data
}

function generateImage(data) {
  const html = `
    <img src=${data} alt/>
    <p>Click to view images of ${select.value}s</p>
  `;
  card.innerHTML = html; // set the card innerHTML which included the fetched data
}

function fetchBreedImage() {
  const breed = select.value;
  const img = card.querySelector('img'); // save the image element to a constant
  const p = card.querySelector('p');

  fetchData(`https://dog.ceo/api/breed/${breed}/images/random`)
    .then( data => {
      img.src = data.message; // set the image source to the new source
      img.alt = breed;
      p.textContent = `Click to view more images of ${breed}`;
    })
}

// ------------------------------------------
//  EVENT LISTENERS
// ------------------------------------------
select.addEventListener('change', fetchBreedImage); // when you select a new option, fetch a new image
card.addEventListener('click', fetchBreedImage); // when you click the card, fetch a new image
form.addEventListener('submit', postData);

// ------------------------------------------
//  POST DATA
// ------------------------------------------

function postData(e) {
  e.preventDefault();
  const name = document.getElementById('name').value;
  const comment = document.getElementById('comment').value;

  const config = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ name, comment})
  }

  fetch('https://jsonplaceholder.typicode.com/comments', config)
  .then(checkStatus)  
  .then( res => res.json() )
  .then( data => console.log(data) )
  .catch( err => console.error('Looks like there was a problem', err) )
}