I have a problem to delete data in nuxtjs:
<tr v-for="(user, index) in paginatedUsers">
<td>{{user.name}}</td>
<td>{{user.email}}</td>
<td>{{user.created_at}}</td>
<td><a class="btn btn-danger btn-sm" href="#" #click="deleteUser(index)">Remove</a></td>
</tr>
deleteUser(index){
this.$axios.$delete(`/users/` + this.users.data[index].id)
.then(({data}) =>{
this.users.data.splice(index, 1);
})
.catch(errors => {
console.log(errors);
});
},
when click on any of the items, get the following error
Cannot read property '0' of undefined
OR
Cannot read property '12' of undefined
how solve this error
You should do this:
this.$axios.$delete(`/users/${this.users[index].id}`)
...
Related
I'm trying to load in data from the database dynamically with javascript and this helper function.
The function fetches a URLs which is routed to actions that return the parameters and a message after completion (as a Promise). The message gets displayed to the end user.
parasails register Page:
methods: {
loadData: async function(url) {
let origin = window.location.origin
url = new URL(origin + url);
try{
let res = await parasails.util.backendLoad(url)
console.log(res)
this.categories = res.categories
this.showResponse = res.showResponse
}catch(err){
console.log("Error: " + err)
}
},
destroyOne: async function(id) {
url = "/api/v1/category/" + id + "/destroy"
this.loadData(url);
}
}
parasails utility:
parasails.registerUtility('backendLoad', async function backendLoad(url) {
return new Promise((resolve)=>{
fetch(url)
.then((res)=>{
if (res.ok)return res.json();
throw new Error(res.status);})
.then((data)=>{
console.log(data);
resolve(data);
})
.catch((err)=>{
let resErr = []
switch(err.message){
case "401":
console.log("an error has occured of type 401");
resErr= {showResponse: {type: 'alert-danger', message "Unauthorized"}};
resolve(resErr);
default:
console.log("an error has occured");
resErr= {showResponse: {type: 'alert-danger', message: "Unkownerror"}};
resolve(resErr);
}
})
});
});
EJS:
<div id="indexCategory" v-cloak>
<div class="container my-2">
<div :class="'alert ' + showResponse.type" role="alert" v-if="showResponse">
{{showResponse.message}}
</div>
<h1>Categories</h1>
<hr/>
<table class="table table-hover">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr scope="row" v-for="c in categories">
<td>
{{ c.name }}
</td>
<td>
<a class="btn btn-outline-secondary btn-sm" #click="destroyOne(c.id)">Delete</a>
</td>
</tr>
</tbody>
</table>
<a type="button" class="btn btn-primary mt-4" href="/category/new">Add</a>
<a type="button" class="btn btn-primary mt-4" href="/dashboard">Back to dashboard</a>
</div>
</div>
The function loadData is called beforeMount and returns all categories as it should.
When destroyOne calls the loadData function this doesnt happen. Neither the categories nor the message get shown. The action returns the parameters as expected (as a Promise).
There are no console outputs either when calling with destroyOne.
What changes do I need to implement, so that the response from destroyOne gets shown?
I'm building a component on my project, which is actually getting all the data and console logging it, but here's the problem: Inside my array of clients, i have some objects (address, documents, ...), and i can't manage to call them on my table.
My script:
<script>
export default {
data: () => ({
clients: [],
}),
methods: {
getClients() {
this.$api
.get("/api_v1/clientes", {
})
.then((response) => {
this.clients = response.data[0];
console.log(response.data);
})
.catch((e) => {
console.log(e);
});
},
},
mounted() {
this.getClients();
},
};
</script>
My table (inside ):
<tbody>
<tr v-for="client in clients" v-bind:key="client.id">
<td>{{ client.id }}</td>
<td>{{ client.name }}</td>
<td>{{ client.email }}</td>
<td>{{ client.documents.cpf || client.documents.cnpj }}</td>
<td>{{ client.documents.celular }}</td>
<td>{{ client.status }}</td>
<td v-if="client.address">
{{ `${client.address.localidade} / ${client.address.uf}` }}
</td>
<td v-else>-</td>
<td>
<a :href="`/see-client/${client.id}`"
><i class="icon-magnifier"></i
></a>
<i class="icon-check" style="color: green"></i>
<i class="icon-close" style="color: red"></i>
</td>
</tr>
</tbody>
My controller:
public function index(Request $request)
{
$data = [
'pag' => 'All clients',
'link' => '/'
];
return view('clients.index', $data);
}
The data:
Someone have a clue of a different approach i could have? I'm using Vue2. It's one of my first big projects, so previously sorry for any rookie mistake. Thanks for your time and help!
This line is only getting the first client:
this.clients = response.data[0];
response.data is your array of clients (from the looks of things). When you use .data[0], you're getting the first element of the array (i.e. the first client).
Then, this line is trying to loop over 1 client, not an array of clients.
<tr v-for="client in clients" v-bind:key="client.id">
Try changing
this.clients = response.data[0];
to
this.clients = response.data;
If that doesn't work (it looks like you've got a weird data structure), try this instead:
this.clients = response.data.data;
Or this (it's unclear to me how many nested data properties you have):
this.clients = response.data.data.data;
I just made a quick analysis about your code. I think you should polish it a little bit.
Let me start with a quick catch up:
Update yuor js section with:
<script>
export default {
// Please do use the function format instead of lambda expression, it's recommended in the vue2 docs.
data() {
return {
clients: [],
};
},
methods: {
// Change this to an async method, so you can have more control on your code.
async getClients() {
try {
/**
* Here, you should have to know, that your file `routes/api.php` hass all of the prefixed /api routes
* So you have a direct access to /api prefixed routes
* Additionally read a little bit about destructuring.
*/
const response = await this.$api.get("/api/clientes");
// Now, please notice that you have 2 data path names.
this.clients = response.data.data; // {or please follow the correct path to the array container of the clients}.
} catch (e) {
console.log("Check this error: ", e);
}
},
},
// Now, change your mounted to an async method
async mounted() {
// Trust me this is going to work perfectly.
await this.getClients();
},
};
</script>
Now, please, please change your api controller logic to a response()->json(...)
public function index(Request $request)
{
// Your retrieve logic...
return response()->json($data);
}
Finally if you have successfully configured everything abouve, your vue component should be able to retrieve the information correctly, and your tbody must work this way...
<tbody>
<tr v-for="client in clients" v-bind:key="client.id">
<td>{{ client.id }}</td>
<td>{{ client.name }}</td>
<td>{{ client.email }}</td>
<td>{{ client.documents.cpf || client.documents.cnpj }}</td>
<td>{{ client.documents.celular }}</td>
<td>{{ client.status }}</td>
<td v-if="client.address">
<!-- You can replace what you have with: -->
{{ client.address.localidade }} / {{ client.address.uf }}
</td>
<td v-else>
-
</td>
<td>
<a :href="`/see-client/${client.id}`">
<i class="icon-magnifier"></i>
</a>
<i class="icon-check" style="color: green"></i>
<i class="icon-close" style="color: red"></i>
</td>
</tr>
</tbody>
I want to create function load more in my search result with vue js and laravel.
This is what I try.
My form code to search
<form #submit.prevent="search">
<input v-model="term" type="search">
<button class="btn btn-success" type="submit">Search</button>
</form>
here is to show search result
<tr v-for="(result, index) in results.data">
<td>{{ result.artist_name }}</td>
<td>{{ result.gender }}</td>
<td>{{ result.created_at }}</td>
<td>{{ result.updated_at }}</td>
</tr>
<div v-if="results.next_page_url" class="card-footer">
<button #click.prevent="paginatesearch(results.next_page_url)" type="button">Load More</button>
</div>
here is my data variable
data() {
return {
term:'',
results:[],
}
},
Here is my code to showing search result.
search() {
let formData = new FormData();
formData.append('term', this.term);
axios.post('/api/artist/search/', formData)
.then((response) => {
this.SearchDiv = true;
this.IndexDiv = false;
this.results = response.data;
this.noResults = this.results.length === 0;
});
},
and this is my code to show load more data
paginatesearch(url = '') {
this.loading = true;
this.disabled = 1;
axios.get(url ? url : '/api/artist/search/')
.then(response => {
this.loading = false;
this.disabled = 0;
if (! this.results.data) {
this.results = response.data
}
else {
this.results.data.push(...response.data.data)
this.results.next_page_url = response.data.next_page_url
}
})
.catch(e => console.error(e))
},
But when I click the button, it give me
TypeError: Cannot convert undefined or null to object
Here is my full code if u need it https://github.com/jazuly1/nginx/blob/master/loadmorewithsearch.vue
'results'is defined as an array, but is used as an object.
just need a simple correction..
in search method change axios.post('/api/artist/search/', formData) to axios.post('/api/artist/search/' + this.$data.term)
and in paginatesearch method change axios.get to axios.post.
and some correction in controller page. now everything is working fine.
I have the following code in my controller.
router.get('/', function(req, res, next) {
Appointment.find().then((appointments) => {
console.log(appointments);
res.render('adminappointments', { title: 'Admin-Appointments', appointlink: true, layout: 'adminlayout', appointment: appointments });
}, (err) => {
res.status(400).send(err);
})
});
And in my hbs page
<tbody>
{{#each appointmentt}}
<tr>
<td>{{this._id}}</td>
<td>{{this.name}}</td>
<td>{{this.email}}</td>
<td>{{this.purpose}}</td>
<td>{{this.clinic}}</td>
<td>{{this.message}}</td>
<td>
<button class="btn btn-small btn-inverse"><i class="icon-trash"></i> Delete</button></td>
</tr>
{{/each}}
</tbody>
The table shows no data, but console log is showing the data. Need help.
I am very new to this i dont know how to delete a row by using fetch.. ive already made a messed up code i don't know how it will work now please help me im so lost...
renderItem(d, i) {
return <tr key={i} >
<td> {d.Employee_ID} </td>
<td>{d.Employee_Name}</td>
<td>{d.Address }</td>
<td><center><button className ="btn btn-info" onClick={this.handleOnclick.bind(this, d.Employee_ID, d.Employee_Name, d.Address)} data-toggle="modal" data-target="#UpdateEmployee">Edit</button></center></td>
<td><center><button className ="btn btn-danger" onClick={this.deleteEmployee.bind(this, d.Employee_ID)}>Delete</button></center></td>
</tr>
}
handleOnclick(id,name,address) {
this.setState({
Employee_Name: name,
Address: address,
});
}
deleteEmployee(id) {
debugger
fetch ('http://localhost:5118/api/employeedetails/deleteemployeedetail/'+ id,
{ method: 'DELETE',})
.then(
res => this.setState({jsonReturnedValue : json})
)
.catch( err => cosole.error(err))
}
After deleting your element from api you also need to remove it from your state, Suppose you are rendering your table from state employee. then you need to do
deleteEmployee(id) {
debugger
fetch ('http://localhost:5118/api/employeedetails/deleteemployeedetail/'+ id,
{ method: 'DELETE',})
.then(
res => {
this.setState({jsonReturnedValue : json})
var employee = [...this.state.employee];
var idx = employee.findIndex(item => item.Employee_ID === id);
employee.splice(idx, 1);
this.setState({employee})
}
)
.catch( err => cosole.error(err))
}