Expected Object, got Array laravel vue pagination - vue.js

hi guys am sure we all use the laravel vue pagination , and i have used it in the past but getting errors now , cant tell why.
so i have my getresults method
getResults(page = 1) {
axios.get('api/category?page=' + page)
.then(response => {
this.categories = response.data;
});
}
my data that am returning i.e categories{} (which is an object)
data() {
return {
categories: {},
// Create a new form instance
form: new Form({
id:'',
name: '',
active: ''
}),
}
},
and finally the pagination
<pagination :data="categories" #pagination-change-page="getResults">
<span slot="prev-nav">< Previous</span>
<span slot="next-nav"> Next ></span>
</pagination>
but am getting error
type check failed for prop "data". Expected Object, got Array
even its an object , please in need of assistance. thanks

hi guys finally solved the error , i had to restructure the way i was getting my my data from my api
it was this
$categories = Category::latest()->paginate(10);
return response([ 'categories' => CategoryResource::collection($categories), 'message' => 'Retrieved successfully'], 200);
i changed it to this
return Category::latest()->paginate('10');
and that solved the pagination errors . thank you once again

Related

Unable to put value using :value wiht v-model together in VueJS 2

In a page i am fetcing data from API and showing the data in the text field. After that user can change the data and submit the form. I am uanble to show data using :value in the inout field. Its showing conflicts with v-model on the same element because the latter already expands to a value binding internally
I tried to mount the data after it loads. But it is still not showing.
<input v-model="password" :value="credentials.password">
created() {
let txid = this.$route.params.id
this.$axios.get(this.$axios.defaults.baseURL+'/v1/purno/internal/users/'+ txid, {
}).then((response) => {
if (response.data.status == 'error') {
toast.$toast.error('Something Went Wrong at!', {
// override the global option
position: 'top'
})
} else if (response.data.status == 'success') {
if(response.data.data.found ==true) {
this.credentials = response.data.data;
})
}
}
})
});
},
data(){
return {
credentials:[],
password:null
}
},
mounted(){
this.password = this.credentials.password
}
How can i solve this problem? Thanks in advance
Please complete it within the request callback
this.credentials = response.data.data;
this.password = this.credentials.password;
like this in the then callback fn. Try it!
conflicts with v-model on the same element because the latter already expands to a value binding internally error message tells it all
v-model="password" is same as :value="password" #input="password = $event.target.value" (for text and textarea - see here)
So using it together with another :value makes no sense...

vuejs dynamically adding class

Using vuejs 3. In the vuejs app, I have:
data(){
return{
return_prohibited:false
}
}
return_prohibited turns to true when the server returns an error message from a fetch request:
fetch(myUrl,this.myInit)
.then(response => response.json())
.then(data => {
if (data.message) {
this.credits = []
this.debits = []
return_prohibited = true
} // cut for brievity
Html file:
<button #click="previousMonth" id="bouton_mois_prec" :class="{interdit:return_prohibited}" >précédent</button>
I was expecting that the css class interdit would be added to the button each time that return_probibited is true, as per these explanations. But nothing happens.
You should append this. in front of return_prohibited - otherwise you will get errors in the console.

How to display nested json value?

I need to display value for month april. Code:
{{my_dates['2018-04-23']}}
displays:
{
"april":0,
"may":0,
"june":0,
"july":0,
"august":0,
"september":0,
"october":0,
"income_trips":"0.00",
"med_services":"0.00",
"food_services":"0.00",
"accom_services":"0.00",
"collegium":"0.00",
"parking":"0.00",
"wash":"0.00",
"other":"0.00",
"balance":"0.00",
"employees":0,
"season_employees":0,
"complaints":0,
"reviews":0
}
I tried:
{{my_dates['2018-04-23']['april']}}
it's display 0, but I am getting error:
[Vue warn]: Error in render: "TypeError: Cannot read property 'april' of undefined"
The follow json should be in my my_dates http://vpaste.net/3A0Th
Code of app:
var app = new Vue({
el: '#app',
data: {
my_dates: {},
},
methods:
{
getTableData: function()
{
// GET /someUrl
this.$http.get('http://127.0.0.1:8000/ponizovka_get_data').then(response => {
// get body data
this.my_dates = response.body;
}, response => {
// error callback
});
}
},
created: function(){
this.getTableData()
}
})
{{ my_dates['2018-04-23']['april'] }}
You're right. This is the correct way to access this property, but the error could be related to this value been display before assignment or async operation. You can fix by checking on v-if, using short-circuit, using a computed property (#EmileBergeron suggestion) or even a method.
Fix by checking on v-if
<div v-if="my_dates && my_dates['2018-04-23']">
{{ my_dates['2018-04-23']['april'] }}
</div>
Fix using short-circuit
{{ my_dates && my_dates['2018-04-23'] && my_dates['2018-04-23']['april'] }}
Fix with a computed property (#EmileBergeron suggestion)
<span>{{ april }}</span>
computed: {
april () {
if (!this.my_dates || !this.my_dates['2018-04-23'])
return null;
return this.my_dates['2018-04-23']['april'];
}
}
Fix using a method
{{ getMyDate('2018-04-23', 'april') }}
methods: {
getMyDate (date, month) {
if (!this.my_dates || !this.my_dates[date])
return null;
return this.my_dates[date][month];
}
}
There are other approaches like optional-chaining purpose or idx.
https://github.com/tc39/proposal-optional-chaining
https://github.com/facebookincubator/idx
It is because, may be you are getting the data from an async source(fetching from API or something). Unless that data is available vue would try to find my_dates['2018-04-23'] which will be undefined so you are getting that error.
Wait until you have fetched you data and then display it.
You can use v-if for that:
<div v-if="my_dates">{{my_dates['2018-04-23']['april']}}</div>
You might still get that error, even after using v-if, so try using computed for getting the values after that.
I hope it helps.

Vue JS fire a method based on another method's output unique ID

I'm trying to render a list of notes and in that list I would like to include the note's user name based on the user_id stored in the note's table. I have something like this, but at the moment it is logging an error stating Cannot read property 'user_id' of undefined, which I get why.
My question is, in Vue how can something like this be executed?
Template:
<div v-for="note in notes">
<h2>{{note.title}}</h2>
<em>{{user.name}}</em>
</div>
Scripts:
methods:{
fetchNotes(id){
return this.$http.get('http://api/notes/' + id )
.then(function(response){
this.notes = response.body;
});
},
fetchUser(id){
return this.$http.get('http://api/user/' + id )
.then(function(response){
this.user = response.body;
});
}
},
created: function(){
this.fetchNotes(this.$route.params.id)
.then( () => {
this.fetchUser(this.note.user_id);
});
}
UPDATE:
I modified my code to look like the below example, and I'm getting better results, but not 100% yet. With this code, it works the first time it renders the view, if I navigate outside this component and then back in, it then fails...same thing if I refresh the page.
The error I am getting is: [Vue warn]: Error in render: "TypeError: Cannot read property 'user_name' of undefined"
Notice the console.log... it the returns the object as expected every time, but as I mentioned if refresh the page or navigate past and then back to this component, I get the error plus the correct log.
Template:
<div v-for="note in notes">
<h2>{{note.title}}</h2>
<em>{{note.user.user_name}}</em>
</div>
Scripts:
methods:{
fetchNotes(id){
return this.$http.get('http://api/notes/' + id )
.then(function(response){
this.notes = response.body;
for( let i = 0; i < response.body.length; i++ ) {
let uId = response.body[i].user_id,
uNote = this.notes[i];
this.$http.get('http://api/users/' + uId)
.then(function(response){
uNote.user = response.body;
console.log(uNote);
});
}
});
},
}
It looks like you're trying to show the username of each note's associated user, while the username comes from a different data source/endpoint than that of the notes.
One way to do that:
Fetch the notes
Fetch the user info based on each note's user ID
Join the two datasets into the notes array that your view is iterating, exposing a user property on each note object in the array.
Example code:
let _notes;
this.fetchNotes()
.then(notes => this.fetchUsers(notes))
.then(notes => _notes = notes)
.then(users => this.joinUserNotes(users, _notes))
.then(result => this.notes = result);
Your view template would look like this:
<div v-for="note in notes">
<h2>{{note.title}}</h2>
<em>{{note.user.name}}</em>
</div>
demo w/axios
UPDATE Based on the code you shared with me, it looks like my original demo code (which uses axios) might've misled you into a bug. The axios library returns the HTTP response in a data field, but the vue-resource library you use returns the HTTP response in a body field. Attempting to copy my demo code without updating to use the correct field would cause the null errors you were seeing.
When I commented that axios made no difference here, I was referring to the logic shown in the example code above, which would apply to either library, given the field names are abstracted in the fetchNotes() and fetchUsers().
Here's the updated demo: demo w/vue-resource.
Specifically, you should update your code as indicated in this snippet:
fetchInvoices(id) {
return this.$http.get('http://localhost/php-api/public/api/invoices/' + id)
// .then(invoices => invoices.data); // DON'T DO THIS!
.then(invoices => invoices.body); // DO THIS: `.data` should be `.body`
},
fetchCustomers(invoices) {
// ...
return Promise.all(
uCustIds.map(id => this.$http.get('http://localhost/php-api/public/api/customers/' + id))
)
// .then(customers => customers.map(customer => customer.data)); // DON'T DO THIS!
.then(customers => customers.map(customer => customer.body)); // DO THIS: `.data` should be `.body`
},
Tony,
Thank you for all your help and effort dude! Ultimately, with the help from someone in the Vue forum, this worked for me. In addition I wanted to learn how to add additional http requests besides the just the user in the fetchNotes method - in this example also the image request. And this works for me.
Template:
<div v-if="notes.length > 0">
<div v-if="loaded === true">
<div v-for="note in notes">
<h2>{{note.title}}</h2>
<em>{{note.user.user_name}}</em>
<img :src="note.image.url" />
</div>
</div>
<div v-else>Something....</div>
</div>
<div v-else>Something....</div>
Script:
name: 'invoices',
data () {
return {
invoices: [],
loaded: false,
}
},
methods: {
fetchNotes: async function (id){
try{
let notes = (await this.$http.get('http://api/notes/' + id )).body
for (let i = 0; notes.length; i++) {
notes[i].user = (await this.$http.get('http://api/user/' + notes[i].user_id)).body
notes[i].image = (await this.$http.get('http://api/image/' + notes[i].image_id)).body
}
this.notes = this.notes.concat(notes)
}catch (error) {
}finally{
this.loaded = true;
}
}

Vue and data from REST API

While playing around with vue.js I noticed some strange behavior while trying to display on a page data from an API, but here's the strange thing :
using vue 2.0.0, i can see the "Title", but I have an error in dev console [see printscreen]
using the latest vue version, i can't see the "Title" [and I have the same error in the printscreen]
Is it normal, or?
Source code :
template:
'<div>'+
'Form with id = {{id}}'+
'<br/>'+
'has title = {{item.details.Title}}'+
'</div>',
data: function(){
return {
id: '',
item: {}
}
},
created: function() {
this.get()
},
methods: {
get: function() {
var self = this
id = window.location.hash
id = id.replace('#/whatever/','')
axiosInstance.get('/thebackendresource/'+id) // <--- make http calls etc
.then(function (response) {
self.id = id
self.item = response.data
console.log(self.item)
}).catch(function (error) {
console.log(error)
}
);
}
}
You are getting this error, because when you are fetching data from axiosinstance, that time item.details is null, and when it tries to render it throws this error.
Once the api call is completed, it updates the the DOM and in turn re-renders the DOM, so you can see item.details.Title rendered.
You need to add a null check to prevent this error, which can be easily done using v-if, like follwoing:
template:
'<div>'+
'Form with id = {{id}}'+
'<br/>'+
'<span v-if="item.details"> has title = {{item.details.Title}}'+
'</span>' +
'</div>',