I want to build a Vue frontend over API data. I can retrieve and delete contents. But i can neither Create nor update content in Vue. I know it's an issue with my Vue script because the API works fine without the frontend. My application is built using Laravel 5.8
The following are my API routes:
//Show a headline
Route::get('Headlines/{id}', 'NewsheadlinesController@show');
//List all headlines
Route::get('Headlines', 'NewsheadlinesController@index');
//Create a headline
Route::post('Headline', 'NewsheadlinesController@store');
//Update a headline
Route::put('Headline', 'NewsheadlinesController@store');
//Delete a headline
Route::delete('Headline/{id}', 'NewsheadlinesController@destroy');
My web.php route:
Route::get('/', function () {
return view('layouts.headline');
});
Here's my Vue component register:
Vue.component('navbar', require('./components/Navbar.vue').default);
Vue.component('headlines', require('./components/Headlines.vue').default);
Navbar.vue component:
<template>
<nav class="navbar navbar-expand-sm navbar-dark bg-info mb-2">
<div class="container">
<a href="#" class="navbar-brand">News Headlines</a>
</div>
</nav>
</template>
Headlines.vue component markup:
<template>
<div>
<h2>Headlines</h2>
<div class="row">
<div class="col-sm-12 col-md-4 col-lg-4">
<h3>Create News Headlines</h3>
<form @submit.prevent="addHeadline">
<div class="form-group">
<input type="text" class="form-control" placeholder="Enter Title" v-model="headline.title" required>
</div>
<div class="form-group">
<textarea class="form-control" placeholder="Enter summary" v-model="headline.description" required></textarea>
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="Unique identification or alias of the curator or correspondent" v-model="headline.identity" required>
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="Name of the curator or correspondent" v-model="headline.name" required>
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="Enter URL for this News Headline" v-model="headline.url" required>
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="Enter URL to photo image" v-model="headline.urlToImage" required>
</div>
<div class="form-group">
<textarea class="form-control" placeholder="Enter full content" v-model="headline.content" required></textarea>
</div>
<div class="form-group">
<select class="form-control" v-model="headline.category" required>
<option value="">Select news category</option>
<option value="health">Health</option>
<option value="science">Science</option>
<option value="general">General</option>
<option value="technology">Technology</option>
<option value="entertainment">Entertainment</option>
</select>
</div>
<div class="form-group">
<select class="form-control" v-model="headline.language" required>
<option value="">Select your language</option>
<option value="nl">Netherlands</option>
<option value="ch">Chinese</option>
<option value="en">English</option>
<option value="fr">French</option>
<option value="es">Spanish</option>
</select>
</div>
<div class="form-group">
<select class="form-control" v-model="headline.country" required>
<option value="">Select you country</option>
<option value="ru">Russia</option>
<option value="nl">Netherlands</option>
<option value="ch">China</option>
<option value="uk">United Kingdom</option>
<option value="fr">France</option>
<option value="us">USA</option>
<option value="sp">Spain</option>
</select>
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="Set publication time for this Headline" v-model="headline.publishedAt" required>
<small class="form-text text-muted">Year-Month-Day Hour:Minute:Second => 2001-03-07 04:05:20</small>
</div>
<div class="form-group">
<input type="text" class="form-control" disabled="" value="2001-03-07 04:05:20" v-model="headline.created_at" required>
<small class="form-text text-muted">Creation time for this Headline => Year-Month-Day Hour:Minute:Second</small>
</div>
<div class="form-group">
<input type="text" class="form-control" disabled="" value="2001-03-07 04:05:20" v-model="headline.updated_at" required>
<small class="form-text text-muted">Last editing time for this Headline => Year-Month-Day Hour:Minute:Second</small>
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="Enter photo caption" v-model="headline.diskImageFileName" required>
<small class="form-text text-muted">Maximum is 30 characters</small>
</div>
<button type="submit" class="btn btn-dark btn-block">Upload</button>
</form>
</div>
<div class="col-sm-12 col-md-8 col-lg-8">
<nav aria-label="News headline pagination">
<ul class="pagination">
<li v-bind:class="[{disabled: !pagination.prev_page_url}]" class="page-item">
<a class="page-link" href="#" @click="fetchHeadlines(pagination.prev_page_url)">
Previous
</a>
</li>
<li class="page-item disabled">
<a class="page-link text-dark" href="">
Page of
</a>
</li>
<li v-bind:class="[{disabled: !pagination.next_page_url}]" class="page-item">
<a class="page-link" href="#" @click="fetchHeadlines(pagination.next_page_url)">
Next
</a>
</li>
</ul>
</nav>
<div class="card card-body mb-2" v-for="headline in headlines" v-bind:key="headline.id">
<h3></h3>
<div class="row col-offset-md-2 col-md-10 mb-2">
<div class="col-sm-12 col-md-8 col-lg-8">
<p><b>Category:</b> . <br><b>Created by: </b> <br>
<i>Created on . <br>Published on </i><br>
<b>Country ISO code:</b> . <b>Language: </b> <br></p>
<p>Post ID: </p>
</div>
<div class="col-sm-12 col-md-4 col-lg-4">
<img style="height: 150px; width: 200%; display: block;" src="" alt="">
</div>
</div>
<p><b>Summary:</b> </p>
<p><b>Content:</b> </p>
<button @click="editHeadline(headline)" class="btn btn-warning mb-2">Edit news</button>
<button @click="deleteHeadline(headline.id)" class="btn btn-danger">Delete news</button>
</div>
</div>
</div>
</div>
</template>
Headlines.vue component script:
<script>
export default {
data() {
return {
headlines: [],
headline: {
id: '',
identity: '',
name: '',
title: '',
description: '',
url: '',
urlToImage: '',
publishedAt: '',
content: '',
category: '',
language: '',
country: '',
diskImageFileName: '',
created_at: '',
updated_at: ''
},
headline_id: '',
pagination: {},
edit: false
};
},
created() {
this.fetchHeadlines();
},
methods: {
fetchHeadlines(page_url){
let vm = this;
page_url = page_url || 'api/Headlines';
fetch(page_url)
.then(res => res.json())
.then(res => {
this.headlines = res.data;
vm.makePagination(res.meta, res.links);
})
.catch(err => console.log(err));
},/* end fetchHeadlines */
makePagination(meta, links) {
let pagination = {
current_page: meta.current_page,
last_page: meta.last_page,
first_page_url: links.first,
last_page_url: links.last,
next_page_url: links.next,
prev_page_url: links.prev
};
this.pagination = pagination;
},/* end makePagination */
deleteHeadline(id) {
if(confirm('Deleting a news headline is irreversible. Are you sure you want to delete it?')) {
fetch(`api/Headline/${id}`, {
method: 'delete'
})
.then(res => res.json())
.then(data => {
alert('The news headline has been removed');
this.fetchHeadlines();
})
.catch(err => console.log(err));
}
},/* end deleteHeadline */
addHeadline() {
if (this.edit === false) {
//Add this new news headline
fetch('api/Headline', {
method: 'post',/*
description: JSON.stringify(this.headline),
content: JSON.stringify(this.headline),*/
headers: {
'content-type': 'application/json'
}
})
.then(res => res.json)
.then(data => {
this.headline.title = '';
this.headline.identity= '';
this.headline.name= '';
this.headline.title= '';
this.headline.description= '';
this.headline.url= '';
this.headline.urlToImage= '';
this.headline.publishedAt= '';
this.headline.content= '';
this.headline.category= '';
this.headline.language= '';
this.headline.country= '';
this.headline.diskImageFileName= '';
this.headline.created_at= '';
this.headline.updated_at= '';
alert('Your News Headline has been added. Thanks for the contribution.');
this.fetchHeadlines();
})
}
else {
//Just update
fetch('api/Headline', {
method: 'put',
description: JSON.stringify(this.headline),
content: JSON.stringify(this.headline),
headers: {
'content-type': 'application/json'
}
})
.then(res => res.json)
.then(data => {
this.headline.title = '';
this.headline.identity= '';
this.headline.name= '';
this.headline.title= '';
this.headline.description= '';
this.headline.url= '';
this.headline.urlToImage= '';
this.headline.publishedAt= '';
this.headline.content= '';
this.headline.category= '';
this.headline.language= '';
this.headline.country= '';
this.headline.diskImageFileName= '';
this.headline.created_at= '';
this.headline.updated_at= '';
alert('Your News Headline has been updated. Thanks for the contribution.');
this.fetchHeadlines();
})
}
},/* end addHeadline */
editHeadline(headline) {
this.edit = true;
this.headline.id = headline.id;
this.headline.headline_id = headline.id;
this.headline.identity = headline.identity;
this.headline.name = headline.name;
this.headline.title = headline.title;
this.headline.description = headline.description;
this.headline.url = headline.url;
this.headline.urlToImage = headline.urlToImage;
this.headline.publishedAt = headline.publishedAt;
this.headline.content = headline.content;
this.headline.category = headline.category;
this.headline.language = headline.language;
this.headline.country = headline.country;
this.headline.diskImageFileName = headline.diskImageFileName;
this.headline.created_at = headline.created_at;
this.headline.updated_at = headline.updated_at;
}
}
};
</script>
Frontend page, 'layouts.headline':
<!doctype html>
<html lang="">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Protect against cross site forgery -->
<meta name="csrf-token" content="">
<script>
window.Laravel = { csrfToken: '' }
</script>
<link href="" rel="stylesheet">
<!-- Title of this page -->
<title>News Headlines with Vue</title>
<!-- Fonts -->
<link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">
</head>
<body>
<div id="app">
<navbar></navbar>
<div class="container">
<headlines></headlines>
</div>
</div>
<link href="">
<link href="">
<link href="">
<script src=""></script>
</body>
</html>
Pardon me, for the lengthy code. 'Just want to give full info.
via Chebli Mohamed
Aucun commentaire:
Enregistrer un commentaire