Can't get data in laravel vue - laravel

I try to show detail of my posts by slugs but data won't render. i just get my navbar and white page,
Code
controller
public function single($slug)
{
$post = Post::where('slug', $slug)->first();
return response()->json([
"post" => $post
], 200);
}
single.vue where i show my single post data
<template>
<div class="post-view" v-if="post">
<div class="user-img">
<img src="...." alt="">
</div>
<div class="post-info">
<table class="table">
<tr>
<th>ID</th>
<td>{{ post.id }}</td>
</tr>
<tr>
<th>Title</th>
<td>{{ post.title }}</td>
</tr>
<tr>
<th>Body</th>
<td>{{ post.body }}</td>
</tr>
</table>
<router-link to="/blog">Back to all post</router-link>
</div>
</div>
</template>
<script>
export default {
created() {
if (this.posts.length) {
this.project = this.posts.find((post) => post.slug == this.$route.params.slug);
} else {
axios.get(`/api/posts/${this.$route.params.slug}`)
.then((response) => {
this.post = response.data.post
});
}
},
data() {
return {
post: null
};
},
computed: {
currentUser() {
return this.$store.getters.currentUser;
},
posts() {
return this.$store.getters.posts;
}
}
}
</script>
vuex store.js
state: {
posts: []
},
getters: {
posts(state) {
return state.posts;
}
},
mutations: {
updatePosts(state, payload) {
state.posts = payload;
}
},
actions: {
getPosts(context) {
axios.get('/api/posts')
.then((response) => {
context.commit('updatePosts', response.data.posts);
})
}
}
Question
Why I can't get my post data? is there any mistake in my code?
................................................................................................................................................................................

You're calling /api/posts/${this.$route.params.slug}, which (by REST convention) returns ONE post object.
When setting your post (this.post = response.data.post) you should use response.data (without .post)

Related

How to make array checkbox to work in laravel blade with petite-vue?

I want to create checkboxes which trigger a vue function when a user checks them. These checkboxes are an array. The problem I have is when I check one of the checkboxes, it will check all of them instead of the one I want.
Here is the script in the blade file.
#foreach ($students as $item)
<tr>
<td>{{ $item->student->name }} {{ $item->student_id }}</td>
<td>
<input type="checkbox" value="1" v-model="store.status"
#change="onclick('{{ $schedule->id }}','{{ $item->student_id }}')" id="">
Present
</td>
</tr>
#endforeach
And here is petite-vue script
<script type="module">
import {
createApp, reactive
} from 'https://unpkg.com/petite-vue?module';
createApp({
store: {
status: [],
},
onclick(schedule_id, student_id)
{
const token = '{{ $token }}';
const config = {
headers: { Authorization: 'Bearer ' + token }
}
const data = {schedule_id: schedule_id, student_id: student_id, status: `${this.store.status}`}
axios.post(`http://localhost:10000/api/check-present`, data, config)
.then((result) => {
console.log(result.data);
$('#successModal').modal('show');
})
.catch((err) => {
console.log(err.response)
});
}
}).mount('#app');
I look forward to idea how to solve this problem. Thanks.

Vue / Laravel - Axios post multiple field

I created a component that can add additional fields by pressing a button. I don't know how would I submit this in the database with axios.post and laravel controller. I was able to achieve it in the past with the use of jquery and pure laravel, but I'm confused how to implement it in vue and axios.
Component.vue
<template>
<v-app>
<table class="table">
<thead>
<tr>
<td><strong>Title</strong></td>
<td><strong>Description</strong></td>
<td><strong>File</strong></td>
<td></td>
</tr>
</thead>
<tbody>
<tr v-for="(row, index) in rows" :key="row.id">
<td><v-text-field outlined v-model="row.title" /></td>
<td><v-text-field outlined v-model="row.description" /></td>
<td>
<label class="fileContainer">
<input type="file" #change="setFilename($event, row)" :id="index">
</label>
</td>
<td><a #click="removeElement(index);" style="cursor: pointer">X</a></td>
</tr>
</tbody>
</table>
<div>
<v-btn #click="addRow()">Add row</v-btn>
<v-btn class="success" #click="save()">Save</v-btn>
<pre>{{ rows | json}}</pre>
</div>
</v-app>
</template>
<script>
export default {
data: ()=> ({
rows: []
}),
methods: {
addRow() {
var elem = document.createElement('tr');
this.rows.push({
title: "",
description: "",
file: {
name: 'Choose File'
}
});
},
removeElement(index) {
this.rows.splice(index, 1);
},
setFilename(event, row) {
var file = event.target.files[0];
row.file = file
},
save() {
// axios.post
}
}
}
</script>
Controller.php
public function store(Request $request)
{
// store function
}
save() {
let data = this.rows
axios
.post("Url", {
data
})
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err)
});
}
ref link https://github.com/axios/axios
save() {
axios
.post("/your/uri", {
user_id: 1,
user_name:'jhone doe',
email:'test#test.com'
})
.then(response => {
console.log(response);
})
.catch(error => {
console.log(error)
});
}
You can retrieve your data from your controller $request->user_id,...,$request->email
Tip: if you post any object,you must JSON.stringify(your_json) them and in a response data from controller json_decode($your_json,true) or you need to modify your header file.
Always use '/your/uri' instead of /your/uri/ without trailing '/'
It now works. I'll be posting my code just in case someone encounter the same hurdle. Than you very much to #kamlesh-paul and #md-amirozzaman
Component.vue
<script>
export default {
data: ()=> ({
rows: [],
}),
methods: {
addRow() {
this.rows.push({
corporate_objective_id: '',
kpa: '',
kpi: '',
weight: '',
score: '',
equal: '',
file: {
name: 'Choose File'
}
});
},
removeElement(index) {
this.rows.splice(index, 1);
},
setFilename(event, row) {
var file = event.target.files[0];
row.file = file
},
save() {
const postData = {
data: this.rows
}
console.log(postData)
axios
.post('/api/employee-objective', {postData})
.then(res => { console.log(res) })
.catch(err => { console.log(err) });
}
}
}
</script>
Controller.php
public function store(Request $request) {
foreach($request->data as $data) {
$container = EmployeeObjective::updateOrCreate([
'kpa_info' => $data['kpa'],
'kpi_info' => $data['kpi'],
'kpa_weight' => $data['weight'],
'kpa_score_1' => $data['score'],
'kpa_equal' => $data['equal'],
]);
$container->save();
}
}

Checkbox doesn't save true value

I'm using Laravel 5.6 and Vuejs 2.
If I click on my checkbox and make the value true it's supposed to save a 1 in the database and if I click my checkbox and make the value false it saves a 0.
The problem I'm having is that if I click my checkbox and make it true, it doesn't save the correct value, no changes is made to the database and I don't get any errors. If I click on my checkbox and make it false, it saves the 0 correctly.
I did notice that even when my value is supposed to be true, I do get a false when I dd($category->has('active')
I'm not sure where I'm going wrong or how to fix it.
My vue file
<template>
<div class="card-body">
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">Active</th>
<th scope="col">Title</th>
<th scope="col">Edit</th>
<th scope="col">Delete</th>
</tr>
</thead>
<tbody>
<tr v-for="(category, index) in categoriesNew" >
<td>
<label>checkbox 1</label>
<input name="active" type="checkbox" v-model="category.active" #click="checkboxToggle(category.id)">
</td>
<td>
{{ category.title }}
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
props: ['categories'],
data(){
return {
categoriesNew: this.categories
}
},
methods: {
checkboxToggle(id){
console.log(id);
axios.put('/admin/category/active/'+id, {
categories: this.categoriesNew
}).then((response) => {
//Create success flash message
})
},
},
mounted() {
console.log('Component mounted.')
}
}
</script>
my routes
Route::put('admin/products/updateAll', 'Admin\ProductsController#updateAll')->name('admin.products.updateAll');
Route::put('admin/category/active/{id}', 'Admin\CategoryController#makeActive')->name('admin.category.active');
Route::resource('admin/category', 'Admin\CategoryController');
Route::resource('admin/products', 'Admin\ProductsController');
my CategoryController#makeActive
public function makeActive(Request $request, $id)
{
$category = Category::findOrFail($id);
if($request->has('active'))
{
$category->active = 1;
}else{
$category->active = 0;
}
$category->save();
}
I hope I made sense. If there is anything that isn't clear or if you need me to provide more info, please let me know
Try changing this line
categories: this.categoriesNew
to
categories: category.active
and add a data prop at the top called category.active: ''
I've managed to get it to work. This is what I did.
vue file
<template>
<div class="card-body">
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">Active</th>
<th scope="col">Title</th>
<th scope="col">Edit</th>
<th scope="col">Delete</th>
</tr>
</thead>
<tbody>
<tr v-for="(category, index) in categories" >
<td>
<label>checkbox 1</label>
<input type="checkbox" v-model="category.active" #click="checkboxToggle(category)">
</td>
<td>
{{ category.title }}
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
props: ['attributes'],
data(){
return {
categories: this.attributes,
}
},
methods: {
checkboxToggle (category) {
axios.put(`/admin/category/${category.id}/active`, {
active: !category.active
}).then((response) => {
console.log(response)
})
}
},
mounted() {
console.log('Component mounted.')
}
}
</script>
my routes
Route::put('admin/category/{category}/active', 'Admin\CategoryController#makeActive')->name('admin.category.active');
and my CategoryController#makeActive
public function makeActive(Request $request, $id)
{
$category = Category::findOrFail($id);
if(request('active') === true)
{
$category->active = 1;
}else{
$category->active = 0;
}
$category->save();
}

Retrieve data using axios vue.js

I retrieve data using axios in methods created () like this:
data() {
return {
filterBox: false,
color: [],
sortBy: null,
productType: [],
products: null,
productcolors: null,
categories: null,
active_el: 0,
isActive: false,
categories: null,
inputSearch: '',
}
},
created() {
axios.get('/admin/product_index_vue').then(response => {
this.products = response.data.products.data;
this.productcolors = response.data.productcolors;
this.categories = response.data.categories;
console.log(this.products.length);
}).catch((error) => {
alert("ERROR !!");
});
},
when checking using console.log the data is there :
Vue DevTools :
but when trying to check the mounted () function I get empty data
what is the cause of this problem?
what I really want is to create a filter, but when using this function the data will not appear :
computed: {
filteredProduct: function () {
if (this.products.length > 0) {
return this.products.filter((item) => {
return (this.inputSearch.length === 0 || item.name.includes(this.inputSearch));
});
}
}
},
HTML CODE :
<tr v-for="product in filteredProduct">
<td style="width:20px;">{{product.id}}</td>
<td class="table-img-product">
<img class="img-fluid" alt="IMG">
</td>
<td> {{ product.name }}</td>
<td style="display:none">{{product.product_code}}</td>
<td>{{ product.base_color }}</td>
<td>{{ product.category }}</td>
<td>{{ product.price }}</td>
<td>{{ product.stock }}</td>
<td>{{ product.status }}</td>
<td>
<button type="button" name="button" v-on:click="deleteProduct(product.id,product.product_color_id)">
<i class="fas fa-trash"></i>
</button>
</td>
</tr>
RESULT
app.js:36719 [Vue warn]: Error in render: "TypeError: Cannot read
property 'length' of null"
found in
---> at resources\assets\js\components\products\Product_index.vue
what causes this function to not work and no detected product data?
This is because the computed property will potentially be calculated before the response has been returned.
If your data properties are going to be an array then I would suggest defining them as an array from the beginning. In the data object change the properties to something like e.g.
products: [],
productcolors: [],
Alternatively, you can add an additional check to your computed property method:
filteredProduct: function () {
if (!this.products) {
return [];
}
return this.products.filter((item) => {
return (this.inputSearch.length === 0 || item.name.includes(this.inputSearch));
});
}
this is axios response ont wording
mounted: {
let self = this
axios.get('/admin/product_index_vue').then(response=>{
self.products=response.data.products.data;
self.productcolors =response.data.productcolors;
self.categories=response.data.categories;
console.log(self.products.length);
}).catch((error)=>{
alert("ERROR !!");
});
},

Return image with function show on *ngFor Angular 4

I have a function in component.ts as follow:
getImage(name) {
this._productService.getImage(name).subscribe((response) => {
// ??? my problem is here
});
}
and it's called here
<tr *ngFor="let i of data">
<td>{{ i.id }}</td>
<td><img [src]="getImage(i.image)" alt=""></td>
<td>{{ i.name }}</td>
<td>{{ i.price }}</td>
</tr>
So, how to my function return image?
P/S: my service get image from API ensure proper operation.
Thank for your help!
In your onInit use the below code,
this._productService.index().subscribe((data) => {
this.data = data;
console.log(data);
},
(error) => {
console.log(error);
},
() => {
this.data.forEach((element: IProduct) => {
element.image = element.image === null ? '' : this._productService.getImage((element.image));
});
});
As worked in teamviwer

Resources