Component method response object data binding - vue.js

I am starting to lose my mind in debugging an application that I inherited from a fellow developer who is absent.
I have narrowed down the problem to the following place in code (php files are checked, Vue instances are initialised, there are no syntax errors).
This is my the component that gets initialised:
var RadniStol = Vue.component('radnistol', {
template: '#template-RadniStol',
data() {
return {
tableData: [],
requestData: {
sort: "ID",
order: "DESC"
}
}
},
methods: {
reloadTable: function (event) {
data = this.requestData;
this.$http.post('php/get/radni_stol.php', data).then(response => {
console.log(response.data.bodyText);
this.tableData = response.data.records;
});
},
.
.
.
The PHP file that gets called with the POST method is working correctly, querying the database and echoing the response in a JSON format.
The thing that is making me pull out my hair is the following: the console.log(response.data) outputs the following into the console:
{"records":[{"DODAN_NA_RADNI_STOL":"1","..."}]}
It is an JSON object that I expected to have but when trying to assign it to the data of the component with:
this.tableData = response.data;
or any other way… response.data.records returns ‘undefined’ in the console. I have tryed with JSON.parse() but no success.
When logging types to console:
response variable is a response object with a status 200 and body and bodyText containing the data from the database.
response.data is a string type containing the string JSON with the data from the database.
When trying to use JSON.parse(response.data) or JSON.parse() on anything in the callback of the POST method I get the following error in the console:
RadniStol.js?version=0.1.1:17 Uncaught (in promise) SyntaxError: Unexpected token in JSON at position 0
at JSON.parse (<anonymous>)
at VueComponent.$http.post.then.response (RadniStol.js?version=0.1.1:17)
at <anonymous>
I am really starting to lose my mind over this issue, please help!
Thank you

If response.data is string, with JSON inside, then to access the records field, you should decode it like this:
JSON.parse(response.data).records
Not sure this has something to do with PHP or Vue.js, it is just plain javascript issue.
If it not decodes, than problem is definitely in response.data. For example
{"records":[{"DODAN_NA_RADNI_STOL":"1","..."}]}
is not a valid JSON, because key "..." needs to have some value.
But it seems to me that response.data is already parsed.
What I suggest you to do, is to write handler of the response as separate function, make response object that mimics actual response object by hand, and then test it separately from request. So you could show us request object and function that works with it.

I had the same error and fixed it.
Result will be response.body not response.data.
Here is my code:
getS: function(page) {
this.$http.get('vue-manager?page=' + page).then((response) => {
var data = JSON.parse(response.body);
this.student = data.data.data;
this.pagination = data.pagination;
});
},

Related

Cannot read property 'employee_name' of undefined

Im using Postman platform for testing API. I'm actually new to Postman. So, Currently testing dummy APIs, where i fetched the GET response result from the URI
http://dummy.restapiexample.com/api/v1/employees , when i add validation points :
specifying test description as "name" See below
var response = JSON.parse(responseBody);
tests["name"] = response.data[2].employee_name == "Ashton Cox";
Test operation successfully passed. But when using specific id in the URI link
http://dummy.restapiexample.com/api/v1/employee/5
with same validations points as above, i'm getting response as TypeError: Cannot read property 'employee_name' of undefined, below is the screenshot
The correct reference and syntax would look like this:
pm.test("Check User", () => {
const responseJson = pm.response.json();
pm.expect(responseJson.data.employee_name).to.eql("Airi Satou");
});

DataTables: Cannot read property 'length' of undefined, but the JSON is valid

var deptTable = $('#team-table').DataTable( {
"ajax": "/cc/AjaxDashboard/getMyTeam",
"pageLength": 10,
"scrollY": "250px"
});
I have this. The JSON response is just [] as there's no data. I am getting:
Cannot read property 'length' of undefined
I thought [] was valid JSON as per https://jsonlint.com/ and it would show an empty message but I get an error instead
[] is indeed a valid JSON syntax for empty array. The reason you're getting the error is because the data returned from your AJAX doesn't match the DataTable's default expectation.
There are 3 ways you can use with the ajax option:
Give it a string as the AJAX source
Give it a configuration object
Give it a function
And by default, when the AJAX source is given, DataTables expects the returned data to be an array of items with the key data:
{
data: []
}
If your AJAX doesn't return this format, you will get that error. Here is the proof: https://jsfiddle.net/davidliang2008/s2xgof6t/22/
To fix it, you can override the returned format by setting dataSrc to an empty string, like this:
{
ajax: {
url: xxx,
dataSrc: ''
}
}
demo: https://jsfiddle.net/davidliang2008/s2xgof6t/26/
More reads on this custom data source property: https://datatables.net/examples/ajax/custom_data_property.html

Pouchdb query() leaving out documents on emit()

For some reason my filter is not working correctly. It was working fine a moment ago and then for some reason it stopped returning all of the templates and only started returning one of them.
Why might it be returning it twice but only giving me one?
I have the following code:
export async function testMe() {
const company_id = await AsyncStorage.getItem('company_id');
const device_db = new PouchDB(company_id, {});
device_db.query(function(doc, emit){
console.log(doc.type, doc._id, doc._rev);
if(doc.type == 'template') {
emit(doc._id, doc);
}
}).then((result) => {
console.log("Returned", result);
})
}
What is unexpectedly happening is this is what gets returned:
template template_1 18-5918af4c5370d9755d0bb8b6dcb21ea1
template template_2 19-8191dec49dfa8c1a2f03d752a193f09e
template template_3 39-74f3b82ce4a38a501810b5ff31efc593
undefined "dpbcab6843-2cdf-4d4c-87ae-286dcddaac22" "2-8f03f3127771dadd3c8f7beb3e827982"
undefined "dpdc6f6cd0-6c6d-4974-a166-b848a0217af4" "2-0eec1a8d925641aa8bf30e058e6515e7"
undefined "dpe1573a70-a281-4e15-a997-82d8bf8fabfa" "2-d3bbcb81344f61cc94459610695c6670"
template template_3 39-74f3b82ce4a38a501810b5ff31efc593
You can ignore the undefined, but what I am trying to show is look at what gets returned twice:
template template_3 39-74f3b82ce4a38a501810b5ff31efc593
In the Returned console.log(), this is the only thing that gets returned (the last template_3 piece of data, totally ignoring the other templates even though they are both type template):
{"total_rows":6,"offset":0,"rows":[{"key":"template_3","id":"template_3","value":{..}}]}
Edit
It's getting even weirder. I just opened template_2 and did a save (in Cloudant) and synced it with my device to update the _rev and now I get:
template template_1 18-5918af4c5370d9755d0bb8b6dcb21ea1
template template_2 20-c549fe868735ef0099b80f6668af611c
template template_3 39-74f3b82ce4a38a501810b5ff31efc593
undefined "dpbcab6843-2cdf-4d4c-87ae-286dcddaac22" "2-8f03f3127771dadd3c8f7beb3e827982"
undefined "dpdc6f6cd0-6c6d-4974-a166-b848a0217af4" "2-0eec1a8d925641aa8bf30e058e6515e7"
undefined "dpe1573a70-a281-4e15-a997-82d8bf8fabfa" "2-d3bbcb81344f61cc94459610695c6670"
template template_3 39-74f3b82ce4a38a501810b5ff31efc593
template template_2 20-c549fe868735ef0099b80f6668af611c
Which returns (leaving out template_3):
{"total_rows":6,"offset":0,"rows":[{"key":"template_2","id":"template_2","value":{..}}]}
Edit 2
I added:
.catch((err) => {
console.log(err);
})
And get this: {"status":409,"name":"conflict","message":"Document update conflict","error":true}
However, I do the following an all _conflict arrays are empty:
device_db.allDocs({conflicts: true})
.then((data) => {
for (let d of data.rows) {
console.log(d.doc._conflicts);
}
});
I believe temporary queries like this should have a key, otherwise the query would not know what documents you want to select. The example from the PouchDb docs is
db.query(function (doc, emit) {
emit(doc.name);
}, {key: 'foo'}).then(function (result) {
// found docs with name === 'foo'
}).catch(function (err) {
// handle any errors
});
so that documents with a "name" field equal to "foo" are returned by the query. In your query the key appears to be undefined. This might explain the odd results you are getting?

vue js returned value gives undefined error

i want to check the returned value of $http.get() but i get undefined value. Here is my vue js code:
var vm = new Vue({
el: '#permissionMgt',
data: {
permissionID: []
},
methods:{
fetchPermissionDetail: function (id) {
this.$http.get('../api/getComplaintPermission/' + id, function (data) {
this.permissionID = data.permissionID; //permissionID is a data field of the database
alert(this.permissionID); //*****this alert is giving me undefined value
});
},
}
});
Can you tell me thats the problem here?.. btw $http.get() is properly fetching all the data.
You need to check what type is the data returned from the server. If #Raj's solution didn't resolve your issue then probably permissionID is not present in the data that is returned.
Do a colsole.log(data) and check whether data is an object or an array of objects.
Cheers!
Its a common js error. Make the following changes and it will work.
fetchPermissionDetail: function (id) {
var self = this; //add this line
this.$http.get('../api/getComplaintPermission/' + id, function (data) {
self.permissionID = data.permissionID; //replace "this" with "self"
});
},
}
the reason is this points to window inside the anonymous function function()
This is a well known js problem. If you are using es2015 you can use arrow syntax (() => { /*code*/ }) syntax which sets this correctly

xhr.post not getting JSON response

I'm trying to use Dojo to post to my server. The server is returning a JSON response (I have debugged it and know its returning a sensible value) but I'm just getting a 'Syntax error' in the Javascript console when it returns. Any ideas?
function submitStatusUpdate() {
dojo.xhr.post({
form:"statusUpdateForm",
handleAs: "json",
load: function(data){
alert('Saved with id ' + data.id);
},
error: function(err, ioArgs){
// again, ioArgs is useful, but not in simple cases
alert('An error occurred');
console.error(err); // display the error
}
});
}
I've also tried it like this
function submitStatusUpdate() {
var posted = dojo.xhr.post({
form:"statusUpdateForm",
load: function(data){
},
error: function(err, ioArgs){
// again, ioArgs is useful, but not in simple cases
console.error(err); // display the error
}
});
posted.then(function(response){
alert('returned ' + response);
});
}
But the response that gets printed out in my alert just seems to be the HTML for my entire page. I'm expecting a JSON object. I'm struggling to find a simple example that tells me how to submit a form, and then have a callback function that reads the response.
Thanks
EDIT (thanks to Richard for the guidance)
This is the working version.
<script language="Javascript">
dojo.require("dijit.form.Button");
dojo.require("dijit.form.TextBox");
dojo.require("dijit.form.CheckBox");
function sendForm(){
var form = dojo.byId("myform");
dojo.connect(form, "onsubmit", function(event){
// Stop the submit event since we want to control form submission.
dojo.stopEvent(event);
// The parameters to pass to xhrPost, the form, how to handle it, and the callbacks.
// Note that there isn't a url passed. xhrPost will extract the url to call from the form's
//'action' attribute. You could also leave off the action attribute and set the url of the xhrPost object
// either should work.
var xhrArgs = {
form: dojo.byId("myform"),
load: function(data){
// As long as the server is correctly returning JSON responses, the alert will
// print out 'Form posted. ' and then the properties and values of the JSON object returned
alert("Form posted." + data);
},
error: function(error){
// We'll 404 in the demo, but that's okay. We don't have a 'postIt' service on the
// docs server.
alert("error");
}
}
// Call the asynchronous xhrPost
alert("Form being sent...");
var deferred = dojo.xhrPost(xhrArgs);
});
}
dojo.ready(sendForm);
</script>
This is (kind of) what my form looks like. This will work anyway (my real form is much bigger). Interestingly I had to change my normal [input type="submit"...] tag into a [button...] to get it to work properly
<form method="post" id="theform" action="postIt">
<input value="Some text" name="formInput" type="text"/>
<input name="checkboxInput" type="checkbox"/>
<button id="submitButton" type="submit">Send it!</button>
</form>
A JavaScript syntax error on parsing an XMLHttpRequest reply usually indicates invalid data from the server. My favourite tool for monitoring XMLHttpRequest traffic is Firebug. It parses JSON so if there's anything wrong, you'll know immediately.
Once you've determined that the JSON data from the server is valid, have a look at the following example from the Dojo documentation. I think it does what you're trying to do.