I study frontend development at a vocational college in Stockholm, Sweden. We are currently studying the Javascript framework (vue.js) and I am stuck on a task. In we will build a simple app using an API with in the form of cities and the cities’ population.
In the task, we will build an app where cities can be displayed, added, edited and deleted. GET, POST, PUT and DELETE must therefore be used.
The cities should be displayed directly.
When the content of the data (i.e. when cities are added, edited or removed) the information must be updated automatically.
The page should not be reloaded with, for example, location.reload, but the automatic update should take place via the mechanisms in Vue.js.
This is what i was thinking:
A title, two inputs and a submit button, below this i have a list were all the cities will show when the page in loaded. In every list-item i have the name of the city, population count and two buttons, one edit and one delete. Here is the code for this:
<body>
<div id="app">
<h1>Cities API</h1>
<h3>Add City</h3>
<div id="city-form">
<input
v-show="isVisible"
type="text"
placeholder="ID"
v-model="id"
/>
<input
type="text"
placeholder="City"
v-model="name"
/>
<input
type="number"
placeholder="Population"
v-model="population"
/>
<input :disabled="!isValid" type="submit" id="submit-btn" @click="submitCity()" >
</div>
<div>
<ul>
<li
v-for="city in cities"
:key="city.id"
class="city-item"
>
<div class="city-info">
<p>{{ city.name }}</p>
<p>{{ city.population }}</p>
</div>
<div class="city-actions">
<button @click="prepareEditCity(city)">Edit</button>
<button
class="delete-btn"
@click="deleteCity(city.id)"
>Delete
</button>
</div>
<hr />
</li>
</ul>
</div>
</div>
<script src="https://unpkg.com/vue@3"></script>
<script src="index.js"></script>
</body>
I tried to use everything that we have been talking about (data, created, computed, methods). We have also talked about watch.
First i need to fetch the data that should be rendered in the list when the pages has loaded. For this im using a fetch in my methods. Then im using this function in my created() so the fetch will happen as soon as the page is loaded. I have problem to add a city or to delete a city its when im trying to edit a city with PUT im having problem.
The submit button is connected to a submit function that will know if its a new city or a edited city.
When im clicking on edit on a specific city i get the right name and population in the inputs, i have also logged to see if the fetch is sending the right data and it is. Now the problem is that it doesnt update the city automatic, i have to reload the page after the submit for the city to be edited. This my code for this. Can anyone tell me where the problem is? I dont want the answer or the right code sent to me just tell me how i should think so i can figure this one out.
const app = Vue.createApp({
data() {
return {
cities: null,
name: '',
population: '',
id: '',
isVisible: false
}
},
created() {
this.fetchCities()
},
computed: {
isValid() {
return this.name.length > 0 && this.population > 0
}
},
methods: {
fetchCities() {
fetch('https://myapi/cities')
.then((response) => response.json())
.then((result) => {
this.cities = result
})
.catch((error) => {
console.error(error, 'Couldt find cities')
})
},
submitCity() {
if (this.id) {
this.editCity()
} else {
this.addCity()
}
},
addCity() {
fetch('https://myapi/cities', {
body: JSON.stringify({
name: this.name,
population: this.population
}),
headers: {
'Content-Type': 'application/json'
},
method: 'POST'
})
.then((response) => response.json())
.then((result) => {
this.fetchCities()
this.name = ''
this.population = ''
})
.catch((error) => {
console.error('Could not add city')
})
},
deleteCity(cityId) {
if (confirm('Are you really sure you want to delete this city?')) {
fetch(`https://myapi/cities/${cityId}`, {
method: 'DELETE'
})
.then(() => {
this.fetchCities()
})
.catch((error) => {
console.error('Could not delete city')
})
}
},
prepareEditCity(city) {
this.name = city.name
this.population = city.population
this.id = city.id
},
editCity() {
console.log(`Editing city with id: ${this.id}, name: ${this.name}, population: ${this.population}`)
fetch(`https://myapi/cities/${this.id}`, {
body: JSON.stringify({
name: this.name,
population: this.population,
id: this.id
}),
headers: {
'Content-Type': 'application/json'
},
method: 'PUT'
})
.then((response) => response.json())
.then((result) => {
this.fetchCities()
this.name = ''
this.population = ''
this.id = ''
})
.catch((error) => {
console.log('Could not edit city')
})
}
}
}).mount('#app')
2
Answers
I only had to remove the .then((response) => response.json()) in the editCity() function.
You should find your city object in
this.cities
array and update values inside it manually.