Click here to Skip to main content
15,867,488 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi there,

Absolute JS beginner here. Just started a 'Writing JS for the Web' course with following exercise and code, but getting 'unexpected end of JSON input' message upon completion of the exercise. Any idea of what's going wrong? I'm coding in the following Codepen: https://codepen.io/nicolaspatschkowski/pen/GRJBZjy?editors=1111[^]

JavaScript
// Get form elements
const titleInput = document.getElementById('title');
const contentInput = document.getElementById('content');
const submitButton = document.getElementById('submit-button');

const url = 'https://us-central1-open-classrooms-js-for-the-web.cloudfunctions.net/widgets';

// Get DOM elements for showing response
const responseMessage = document.getElementById('response-message');
const responseTitle = document.getElementById('response-title');
const responseId = document.getElementById('response-id');
const responseContent = document.getElementById('response-content');

submitButton.addEventListener('click', ($event) => {
  $event.preventDefault();
  const post = {
    title: titleInput.value,
    content: contentInput.value
  };
  submitFormData(post);
});

function makeRequest(data) {
  return new Promise((resolve, reject) => {
    let request = new XMLHttpRequest();
    request.open('POST', url + '/create-post');
    request.onreadystatechange = () => {
      if (request.readyState === 4) {
        if (request.status === 201) {
          resolve(JSON.parse(request.response));
        } else {
          reject(JSON.parse(request.response));
        }
      }
    };
    request.setRequestHeader('Content-Type', 'application/json');
    request.send(JSON.stringify(data));
  });
}

async function submitFormData(post) {
  try {
const requestPromise = makeRequest(post);
const response = await requestPromise;
responseMessage.textContent = response.message;
responseTitle.textContent = response.post.title;
responseId.textContent = response.post.id;
responseContent.textContent = response.post.content; 
  } catch (errorResponse) { responseMessage.textContent = errorResponse.error;
  }
}; 


What I have tried:

I've already done a bit of research on JSON formatting. Must be something with formatting - parsing, but still unsure, as I'm absolute novice. Thanks in advance!
Posted
Updated 9-Jan-23 3:00am
Comments
0x01AA 7-Jan-23 8:26am    
What is the json data you receive?
For me it looks you get an empty string and therefore json parsing fails.
frontroad 7-Jan-23 8:42am    
I believe the aim of the exercise is to send the 'post' object data to the server and print its response, with the server returning that 'post' object data (so ID, title, content).
0x01AA 7-Jan-23 8:54am    
Then please show what the server responses exactly. This to get a chance to help what's wrong
frontroad 7-Jan-23 8:59am    
I did a console.log to check request.respond and it's showing only an empty string...
0x01AA 7-Jan-23 9:04am    
Yep. Then this is the problem I think. Now it is up to you to figure out, why the server respond with an empty string. Btw, what is the http response code the server replies for your request?

If you get "unexpected end of JSON input" it's not a bug in itself - it's the system reacting to bad JSON data: either no data, or malformed data which is missing closing braces of some kind. That can't be "fixed" because it's not necessarily your JSON processing code that is causing the problem.

You need to start by looking at exactly what JSON data you are processing, and check that for both existence and validity (Online checkers are available: json validator online - Google Search[^], so pick one or two and run your data through them).
WHen you know where the problem is you can start looking at why it's bad - but just a chunk of code without the data doesn't enable anyone to fix a problem!
 
Share this answer
 
What's hampering your ability to debug problems like this is code like this:
JavaScript
resolve(JSON.parse(request.response));
reject(JSON.parse(request.response));
request.send(JSON.stringify(data));

DO NOT COMBINE STATEMENTS LIKE THAT! You cannot see what when parse and stringify methods are generating. Put those results in variables so you can inspect the values before using them in the enclosing methods.
JavaScript
console.log(request.response);
var parsedResponse = JSON.parse(request.response);
console.log(parsedResponse);
resolve(parsedResponse);

If your code is getting back a non-json response, like nothing at all or an error page, your code will still try to parse that as json and you'll get errors like you're seeing.

If you're not getting the response you expected, it's probably because you're not sending the data expected to the API method or not sending it in format the API method is expecting. If that's the case, you'll have to contact the vendor of the API for help on it.
 
Share this answer
 
Your code is making a cross-origin request to us-central1-open-classrooms-js-for-the-web.cloudfunctions.net, but that site does not return any CORS headers:

Cross-Origin Resource Sharing (CORS) - HTTP | MDN[^]

As a result, if you check your browser's developer console, you will see several errors:
Quote:
Cross-Origin Request Blocked:
The Same Origin Policy disallows reading the remote resource at https://us-central1-open-classrooms-js-for-the-web.cloudfunctions.net/widgets/create-post. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 500.

If you switch to using the fetch API, you can specify mode: 'no-cors', which might allow the request to succeed. But you would not be able to read any part of the response.
JavaScript
async function submitFormData(post) {
  try {
    const response = await fetch(url + '/create-post', {
      method: 'POST',
      mode: 'no-cors',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(post)
    });
    
    const result = await response.json();
    responseMessage.textContent = result.message;
    responseTitle.textContent = result.post.title;
    responseId.textContent = result.post.id;
    responseContent.textContent = result.post.content; 
  } catch (errorResponse) {   
    responseMessage.textContent = errorResponse.error;
  }
};
Using the Fetch API - Web APIs | MDN[^]
Fetch API - Web APIs | MDN[^]
Request.mode - Web APIs | MDN[^]
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900