0

I'm fairly new to node.js! I'm trying to write a comment section that's rendered by node.js server. I have a json file, and I pass its value into an ejs file, so far it renders fine. Now I added a comment section, with input field and submit button, so my question is: is it possible to add the input in the comment section back to existing json file, to append new content, then rewrite the json file, then re-render all, after I click the submit button?

I've tried to add event listener to get value, then I try to use JSON.stringfy() to get the string...then I have no clue where to go from now on, because I don't know if the above question is even possible?

In case it's not possible, what should I do to keep my old data, while adding new one and have it render to screen? If database is not involved, then is localStorage my only choice?

Annie
  • 345
  • 2
  • 5
  • 18
  • Is there a reason why you are not using a database for storing the comment data? – Iskandar Reza Mar 22 '19 at 21:35
  • So good to see you asking your first questions. Not sure why you're using JSON files to store your comments list. If you've just started to learn Nodejs then it's ok. I guess this is a duplicate for https://stackoverflow.com/questions/36856232/write-add-data-in-json-file-using-node-js. Although it might work but I don't suggest it at all. A database is what you're seeking. Once you learn how to use one, it's going to be piece of cake. If the link above is not what you're looking for feel free to reply and ask any questions you have :) Best luck on your journey to lean Nodejs – mamsoudi Mar 22 '19 at 21:57
  • Hi guys, I haven't learnt database yet, so I can't use it. This is a practice project, and our teacher requires us to use what we have to solve the problem. – Annie Mar 23 '19 at 09:43
  • @Annie can you show us example code/any attempts? – Lord Elrond Mar 23 '19 at 17:28
  • Hi all, I'm close to solve all my problems, I will share my answer soon! :D – Annie Mar 23 '19 at 17:48

1 Answers1

0

now I more or less solve my problem!

Here are how I solved it. Here is my fans.json (sorry, not nice format after I tested it and have it rewritten many times)

{"comments":[
{"name":"Anna","message":"I love your show last summer in Stockholm! Best summer concert I've been to!"},
{"name":"Jason","message":"This is War is the best album I've ever bought, I can't get tired of listening to it all the time."},
{"name":"Hansel","message":"When are you guys coming to Germany again?"},{"name":"Ash","message":"My favorite song is Up in the Air. It always makes me happy and wanna dance!"}]}

First I created the template in fans.ejs

<section class="content-section container">
      <h2>Dear fans, we'd love to hear from you!</h2>
        <% fans.comments.forEach((comment) => { %>
                <p class="name"><%= comment.name%></p>
                <p class="message"><%= comment.message%></p>
         <% }) %>

     <div id="commentDom">
       </div>
 </section>

 <div class="comment">
        <label for="full-name">Name</label>
         <input id="full-name" name="full-name" type="text"/>
         <label for="message">Comment</label>
          <textarea id="message" name="message"></textarea>
          <button class="btn btn-primary" value="submit">Submit</button>
  </div>

then I wrote this part in this fans.js (there are more to it but I just want to emphasize the part that interacts with server.js

document.querySelector('button').addEventListener('click', (e)=> {
    if (name.trim() === '' || message.trim() === '' ) {
        return
    }

    let commentObj = {
        name: name,
        message: message
    }

    fetch('/fans', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/json'
        },
        body: JSON.stringify(commentObj)
     }).catch((error) => {
         console.log(error)
     })

     generateDom(name, message)
     removeInput()
})

Then I wrote those in the server.js, so the new information gets to be pushed to the my existing fans.json file, then it gets rewritten.

app.post('/fans', (req, res) => {
    fs.readFile('fans.json', (error, data)=>{
        if (error) {
            res.status(500).end()
        } else{
            const fansObj = JSON.parse(data)
            fansObj.comments.push(req.body)
            fs.writeFile('fans.json', JSON.stringify(fansObj), (error) =>{
                if (error){
                    console.log(error)
                } else{
                    console.log('write successfully!')
                }
            })
        }
    })
})

After that I found that I have to refresh my page manually to get updated when I clicked the button. I googled around and it seems I have to use websockets or socket.io to solve this problem, which is out of my knowledge scope so far. So I decided to use the simple way by creating two functions, one is to generatedom in my ejs file, which goes in the "commentDom" section, after the original comment section. Another is to remove the input msg in the input area, I remove the msg in the fans.js as well as the ones in the fans.ejs(let them = ''), after the button is clicked, thus we can create a nice immediate feedback to the user. Of course if they refresh the browser, they will be able to see the "real" rendering from the server side.

Of course I know in the real world more things will be involved, such as database etc. I look forward to learning more on that later. :D

Annie
  • 345
  • 2
  • 5
  • 18