1

I am working on a school project with a team of developers. We have created a page where the users have a profile and that profile can be updated. We have come across a bug when a user updates its information. If I update my city for example, then all other information about my user disappears. I have to update the other fields as well, otherwise the database will only store the city that I recently updated.

What I want is that the information I filled in when I created my user is saved, besides from the information I change when I update my user.

Before update: {"username":"bobox","email":"bobox@hotmail.com","password":"test234","gender":"Man","age":"17","city":"Jönköping","games":"Battlefield V","usernameDiscord":"bigbox","usernameSteam":"bigbox","usernameOrigin":"bobox","_id":"wTs8IyRmcA40f3VN"}

After update: {"username":"bobox","email":"bobox@hotmail.com","password":"test234","gender":"","age":"","city":"New York","games":"","usernameDiscord":"","usernameSteam":"","usernameOrigin":"","_id":"wTs8IyRmcA40f3VN"}

Here is the code. I am thankful for all help. If there is anything else you need to know, just let me know.

Updating a user: script.js

async function updateUser(age, city, gender, games, discord, steam, origin) {
    const id = localStorage.getItem("userId")
    const response = await fetch('http://localhost:8080/users/' + id, {
        method: 'PATCH',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
            age: age,
            city: city,
            gender: gender,
            games: games,
            usernameDiscord: discord,
            usernameSteam: steam,
            usernameOrigin: origin
        })
    })
    console.log(response)
    const data = await response.json()
    console.log(data)
}

function updateUsersIndex() {
    let updateProfileBtn = document.querySelector(".Profile-Right__Update")
    console.log(updateProfileBtn)
    updateProfileBtn.addEventListener("click", async(event) => {
        console.log("hej")
        event.preventDefault()
        const age = document.querySelector(".Age__Input").value
        const city = document.querySelector(".City__Input").value
        const gender = document.querySelector(".Gender__Input").value
        const discord = document.querySelector(".Discord__Input").value
        const steam = document.querySelector(".Steam__Input").value
        const origin = document.querySelector(".Origin__Input").value
        const games = document.querySelector(".Profile-Right__Select-Game").value
        const hidden = document.querySelector(".hidden")
        const updateUsers = await updateUser(age, city, gender, games, discord, steam, origin)
    })
}
updateUsersIndex()

let profileUpdateBackBtn = document.querySelector(".Profile-Right__Back")
profileUpdateBackBtn.addEventListener("click", async(event) => {
    event.preventDefault()
    let updateProfile = document.querySelector(".Update-Profile")
    let profile = document.querySelector(".Profile__Wrappe")
    profile.classList.toggle("Hidden")
    updateProfile.classList.toggle("Hidden")
})

app.js:

app.patch('/users/:id', async(req, res) => {
    const result = await collectionsNEDB.users.update({ _id: req.params.id }, {
        $set: {
            "age": req.body.age,
            "city": req.body.city,
            "gender": req.body.gender,
            "games": req.body.games,
            "usernameDiscord": req.body.usernameDiscord,
            "usernameSteam": req.body.usernameSteam,
            "usernameOrigin": req.body.usernameOrigin
        }
    })
    console.log(req.params.id)
    res.json(result)
})

Creating a user: script.js

async function createUser(username, email, password, repeatPassword, games, usernameDiscord, usernameSteam, usernameOrigin) {
    const response = await fetch('http://localhost:8080/register', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            username: username,
            email: email,
            password: password,
            repeatPassword,
            games: games,
            usernameDiscord: usernameDiscord,
            usernameSteam: usernameSteam,
            usernameOrigin: usernameOrigin

        })
    })
    console.log(response)
    const data = await response.json()
    if (response.status == 200) {
        console.log(data.message)
        if (data.message == "SUCCESS") {
            console.log("Great")
            let Success = document.querySelector(".Success")
            Success.innerHTML = "Användare skapad!"
            alert("Användare skapad!")
        }
    } else {
        const data = await response.json()
        const p = document.querySelector("p")
        p.innerHTML = ""
        for (let i = 0; i < data.errors.length; i++) {
            const error = data.errors[i]
            console.log(data.errors)
            switch (error) {
                case "ERROR_USER_ALREADY_EXISTS":
                    const hidden = document.querySelector(".Error")
                    hidden.classList.toggle("Hidden")
                    hidden.innerHTML = "Användarnamnet existerar redan!"
                    break;
                case "ERROR_EMAIL_ALREADY_EXISTS":
                    const hiddenEmail = document.querySelector(".Error__Email")
                    hiddenEmail.classList.toggle("Hidden__Email")
                    hiddenEmail.innerHTML = "E-mail existerar redan!"
                    break;
                case "ERROR_PASSWORD_MISMATCH":
                    const hiddenPassword = document.querySelector(".Error__Password")
                    hiddenPassword.classList.toggle("Hidden__Password")
                    hiddenPassword.innerHTML = "Lösenordet matchar inte"
                    break;
            }
        }
    }
}

function init() {
    let form = document.querySelector("#Reg-Form-1")
    form.addEventListener("submit", async(event) => {
        event.preventDefault()
        const username = form.querySelector(".username").value
        const email = form.querySelector(".email").value
        const password = form.querySelector(".password").value
        const repeatPassword = form.querySelector(".repeat-password").value
        const games = form.querySelector(".gejms").value
        const usernameDiscord = form.querySelector(".usernameDiscord").value
        const usernameSteam = form.querySelector(".usernameSteam").value
        const usernameOrigin = form.querySelector(".usernameOrigin").value
        const hidden = document.querySelector(".hidden")
        const createUsers = await createUser(username, email, password, repeatPassword, games, usernameDiscord, usernameSteam, usernameOrigin)
    })
}
init()

app.js:

app.post("/register", async(req, res) => {
    let user, email

    if (process.env.NODE_ENV == "development") {
        user = await collectionsNEDB.users.find({ username: req.body.username })
        email = await collectionsNEDB.users.find({ email: req.body.email })
    } else {
        dataUser = await Database.collections.users.find({ username: req.body.username })
        dataEmail = await Database.collections.users.find({ email: req.body.email })
        user = await dataUser.toArray()
        email = await dataEmail.toArray()
    }
    let errors = []
    if (req.body.password !== req.body.repeatPassword) {
        errors.push("ERROR_PASSWORD_MISMATCH")
    } else if (user == false) {
        if (email == false) {
            let newUser = {
                username: req.body.username,
                email: req.body.email,
                password: req.body.password,
                gender: "",
                age: "",
                city: "",
                games: req.body.games,
                usernameDiscord: req.body.usernameDiscord,
                usernameSteam: req.body.usernameSteam,
                usernameOrigin: req.body.usernameOrigin
            }
            if (process.env.NODE_ENV == "development") {
                const result = await collectionsNEDB.users.insert(newUser)
                res.status(200).json({ message: "SUCCESS" })

            } else {
                let db = await Database.connect()
                let users = db.collection("users")
                const result = await users.insert(newUser)
                res.status(200).json({ message: "SUCCESS" })
                console.log(result)
            }
        } else {
            errors.push("ERROR_EMAIL_ALREADY_EXISTS")
        }
    } else {
        errors.push("ERROR_USER_ALREADY_EXISTS")
    }
    if (errors.length > 0) {
        res.status(400).json({ errors: errors })
    }
})
Software Engineer
  • 15,457
  • 7
  • 74
  • 102
hawe
  • 15
  • 5
  • 1
    As far as I can tell the problem is kind of obvious: the update doesn't discriminate between updated and empty fields, it just overwrites everything. Are you aware that is what's happening? Because once you know that, the way forward is kind of obvious, too: either remove any empty / `""` field from the update query, or pre-fill all form inputs with the current values so unchanged fields get overwritten by old values. –  Mar 23 '20 at 09:39
  • Thank you for looking at this @ChrisG I wasn't aware of that having an impact. Although the empty strings are found in the register function and not in the update functions (as far as I can see). So when you register a user you don't fill in age, gender or city. These can only be added once you are logged in and update your users information. The empty strings are there just to make sure the values can be added in databse once you update a user. Or have I completely misunderstood your answer? – hawe Mar 23 '20 at 09:55
  • Yes, I guess you have. The register code doesn't matter one bit. The problem is, again, that submitting the update form overwrites all the fields that are part of the update form. So say you visit the form, enter a city and leave the other fields blank. Submitting it like that will now take *every* field, i.e. the city and a bunch of empty strings, and write it into the database. Overwriting all the previous information with empty strings. –  Mar 23 '20 at 10:05
  • 1
    The solution is to remove empty strings from the `$set` object when you update the user document. Or load all the current information into the form so the fields aren't empty unless they're also empty in the DB. –  Mar 23 '20 at 10:10
  • @ChrisG - You are right of course, but that should be a formal answer – Software Engineer Mar 23 '20 at 10:15

0 Answers0