freeCodeCamp icon indicating copy to clipboard operation
freeCodeCamp copied to clipboard

Error is not logged into the fCC Editor Console

Open nevfy-y opened this issue 3 years ago • 8 comments

Describe the Issue

Hello everyone!

This code passes the tests, when it should not, because I used different names in the argument and the statement of the function:

        .then(whateverString => {
          document.getElementById('message').innerHTML = JSON.stringify(completelyDifferentString)
        })

With this code, tests don't fail, but the button Get Message does nothing when pressed.

It should probably return an error message like "completelyDifferentString" is not defined and should not pass the tests.

Affected Page

https://www.freecodecamp.org/learn/data-visualization/json-apis-and-ajax/get-json-with-the-javascript-fetch-method

Your code

<script>
  document.addEventListener('DOMContentLoaded',function(){
    document.getElementById('getMessage').onclick= () => {
      // Add your code below this line
      fetch('/json/cats.json')
        .then(response => response.json())
        .then(whateverString => {
          document.getElementById('message').innerHTML = JSON.stringify(completelyDifferentString)
        })
      // Add your code above this line
    };
  });
</script>
<style>
  body {
    text-align: center;
    font-family: "Helvetica", sans-serif;
  }
  h1 {
    font-size: 2em;
    font-weight: bold;
  }
  .box {
    border-radius: 5px;
    background-color: #eee;
    padding: 20px 5px;
  }
  button {
    color: white;
    background-color: #4791d0;
    border-radius: 5px;
    border: 1px solid #4791d0;
    padding: 5px 10px 8px 10px;
  }
  button:hover {
    background-color: #0F5897;
    border: 1px solid #0F5897;
  }
</style>
<h1>Cat Photo Finder</h1>
<p id="message" class="box">
  The message will go here
</p>
<p>
  <button id="getMessage">
    Get Message
  </button>
</p>

Expected behavior

Using different names for the argument in the second .then should return an error:

        .then(whateverString => {
          document.getElementById('message').innerHTML = JSON.stringify(completelyDifferentString)
        })
        // error! "completelyDifferentString" is not defined

Tests should only pass if the names match, like so:

        .then(whateverString => {
          document.getElementById('message').innerHTML = JSON.stringify(whateverString)
        })

Screenshots

No response

System

  • Device: [PC]
  • OS: [Manjaro 22.0.0]
  • Browser: [Librewolf]
  • Version: [98.0.2 (64 bit)]

Additional context

No response

nevfy-y avatar Oct 31 '22 11:10 nevfy-y

The test is passed when you use 'completelyDifferentString' but you don't get the output, so that means it is incorrect. The test is not being processed correctly on the freeCodeCamp website.

When you try this code in an actual code editor like Visual Studio you will get an error saying that it is not defined.

sanajaveria97 avatar Nov 01 '22 13:11 sanajaveria97

image

FWIW, the error is not shown on the fCC editor console but, surely, is logged on the browser console. Not sure if there is a way to fix this.

Needs additional investigation.

raisedadead avatar Nov 01 '22 15:11 raisedadead

I'm not sure we can solve this one. Not in a nice way.

The problem is that we need to click on the button, wait for the fetch to complete and check that the dom has been updated appropriately. All of which sounds like it would be hard to pull off in our testing environment.

It might be that we can only catch this through regex.

ojeytonwilliams avatar Nov 01 '22 16:11 ojeytonwilliams

The problem is that we need to click on the button, wait for the fetch to complete and check that the dom has been updated appropriately. All of which sounds like it would be hard to pull off in our testing environment.

Actually, I might have an idea on this. Let me spike on it real quick.

naomi-lgbt avatar Nov 01 '22 18:11 naomi-lgbt

Two hours later... no luck. Despite all my attempts, the DOM won't re-render.

naomi-lgbt avatar Nov 01 '22 20:11 naomi-lgbt

@naomi-lgbt as soon as you said it might be possible, I started doubting my earlier proclamations of doom.

I stand by the 'not nice' part, but this code works, after a fashion:

const catData = [
  {
    "id": 0,
    "imageLink": "https://s3.amazonaws.com/freecodecamp/funny-cat.jpg",
    "altText": "A white cat wearing a green, helmet shaped melon on its head. ",
    "codeNames": ["Juggernaut", "Mrs. Wallace", "Buttercup"]
  },
  {
    "id": 1,
    "imageLink": "https://s3.amazonaws.com/freecodecamp/grumpy-cat.jpg",
    "altText": "A white cat with blue eyes, looking very grumpy. ",
    "codeNames": ["Oscar", "Scrooge", "Tyrion"]
  },
  {
    "id": 2,
    "imageLink": "https://s3.amazonaws.com/freecodecamp/mischievous-cat.jpg",
    "altText":
      "A ginger cat with one eye closed and mouth in a grin-like expression. Looking very mischievous. ",
    "codeNames": ["The Doctor", "Loki", "Joker"]
  }
]
async () => {
    document.getElementById('getMessage').click();
    await new Promise((resolve, reject) => setTimeout(() => resolve(), 250));
    assert.equal(document.getElementById('message').textContent, JSON.stringify(catData));
} 

I couldn't think of any way to test the dom manipulation that wasn't a race, but there you go. Maybe someone can make use of this.

ojeytonwilliams avatar Nov 01 '22 21:11 ojeytonwilliams

Hello,

I agree @ojeytonwilliams's idea but unless timeout parameter is over 500ms instead of 250ms, the test always failed in my local environment. (It may be affected by camper's machine spec or transmission speed)

Simply, using the code written by the camper, It seems that we can avoid passing the test when different names are used in second .then's argument and JSON.stringify method's value like bellow.

const arrangedCode = __helpers.removeWhiteSpace(code);
const jsonDataName = arrangedCode.slice(
  arrangedCode.indexOf('.json()).then(') + '.json()).then('.length,
  arrangedCode.indexOf('document.getElementById(\'message\').innerHTML') - '=>{'.length
);
const stringifyDataName = arrangedCode.slice(
  arrangedCode.indexOf('JSON.stringify(') + 'JSON.stringify('.length,
  arrangedCode.indexOf('JSON.stringify(') + 'JSON.stringify('.length + jsonDataName.length
);

assert(
  arrangedCode.match(
    /document\.getElementById\(('|")message\1\)\.innerHTML=JSON\.stringify\(?\w+\)/g
  ) 
  && jsonDataName === stringifyDataName
  && arrangedCode[arrangedCode.indexOf('JSON.stringify(') + 'JSON.stringify('.length + stringifyDataName.length] === ')'
);

mmatsumoto1026 avatar Nov 04 '22 02:11 mmatsumoto1026

I agree @ojeytonwilliams's idea but unless timeout parameter is over 500ms instead of 250ms, the test always failed in my local environment. (It may be affected by camper's machine spec or transmission speed)

I agree with you that hardcoding a time limit is not good as we cant know how long it will take on the camper's machine.

Simply, using the code written by the camper, It seems that we can avoid passing the test when different names are used in second .then's argument and JSON.stringify method's value like bellow.

const arrangedCode = __helpers.removeWhiteSpace(code);
const jsonDataName = arrangedCode.slice(
  arrangedCode.indexOf('.json()).then(') + '.json()).then('.length,
  arrangedCode.indexOf('document.getElementById(\'message\').innerHTML') - '=>{'.length
);
const stringifyDataName = arrangedCode.slice(
  arrangedCode.indexOf('JSON.stringify(') + 'JSON.stringify('.length,
  arrangedCode.indexOf('JSON.stringify(') + 'JSON.stringify('.length + jsonDataName.length
);

assert(
  arrangedCode.match(
    /document\.getElementById\(('|")message\1\)\.innerHTML=JSON\.stringify\(?\w+\)/g
  ) 
  && jsonDataName === stringifyDataName
  && arrangedCode[arrangedCode.indexOf('JSON.stringify(') + 'JSON.stringify('.length + stringifyDataName.length] === ')'
);

It wont work, for example this is completely valid code and will fail the above test:

fetch('/json/cats.json') .then(response => response.json()) .then(x => { console.log('I want to do something') return x }) .then(data => { document.getElementById('message').innerHTML = JSON.stringify(data); })

KravMaguy avatar Nov 07 '22 00:11 KravMaguy