How can I populate my data from an array in another method?
-
In the code snippet that you provided, you are not using the .push method. In each iteration you are overwriting
tableData
with a single object.
Push is used like this:this.tableData.push({ ... })
-
@chyde90 Thank you for your reply. I have tried using the .push method but am facing the below error. Any way I can workaround this?
request.js?87f7:31 Uncaught TypeError: Cannot read property 'push' of undefined at eval (PageMedication.vue?dfae:272) at Array.forEach (<anonymous>) at Response.eval (PageMedication.vue?dfae:265) at Request.eval (request.js?87f7:364) at Request.callListeners (sequential_executor.js?78b0:106) at Request.emit (sequential_executor.js?78b0:78) at Request.emit (request.js?87f7:683) at Request.transition (request.js?87f7:22) at AcceptorStateMachine.runTo (state_machine.js?f355:14) at eval (state_machine.js?f355:26)
-
Is there any way I can push data into
tableData
in each iteration? -
Use a computed property to compute tableData from reminderData
-
@felice The error tells you that you are calling the .push function on something that is
undefined
. You don’t need a workaround, you need to call the function on the right object (that is, the array)You were on the right track, it should work the way you did, except with .push instead of re-assigning a value to the property (what I said above).
Seems like there is some other problem with your code, but I can’t do much with what you showed us.
-
@rab Thank you for your advice. From what I understood, you mean that I could create a property under
computed: {}
that iterates throughreminderData
. After which I can bind the property totableData
? -
@chyde90 I tried pushing the data into the
tableData
but looks like the data still doesn’t reflect.Here, I am trying to use the data to create a q-list, with
v-for="data in tableData
<q-list bordered> <q-item v-for="data in tableData" :key="data.id" v-ripple> ... </q-item> </q-list>
Here, I have initialized the value in each column to be
null
tableData: [ { id: null, name: null, frequency: null, prescription: null, time: null }]
Here, I am trying to loop through
reminderData
, which stores the data from the database and trying to push the data in each iteration intotableData
above so that it can be reflected in the q-listreminderData.forEach((item) => { let med_id = item.medicine_id; let med_name = item.medicine_name; let med_frequency = item.medicine_frequency; let med_prescription = item.doctor_prescription; let med_time = item.medicine_time; this.tableData.push({id: med_id, name: med_name, frequency: med_frequency, prescription: med_prescription, time: med_time}); });
I think that the
undefined
error is due to it not being able to recognize thetableData
in the.push
method? -
@felice please, provide a more meaningful snippet or explain a bit more context, or best provide a codepen along with your initial explanation, so people don’t go in circles trying to help you.
-
@metalsadman Apologies for the brief explanation on the issue and thank you for your reply. Here is the detailed explanation:
I am creating a quasar web application to fetch and display all the data in my database (I am using AWS DynamoDB) into a quasar list.
Under the
<template>
tag, I have created a<q-list>
where a<q-item>
will be created for every data in tableData -v-for="data in tableData"
.Under the
<script>
tag, I have created thetableData
where each attribute is initialized tonull
. Also, agetReminder()
method is created to retrieve all the data in the database and store them in the array -reminderData
. I want to put every data inreminderData
intotableData
, hence I have tried using aforEach
method to iterate through every data in the array, and the.push
method for pushing the data intotableData
.Results of reminderData printed in the console:
Code Snippet of looping through
reminderData
:reminderData.forEach((item) => { let med_id = item.medicine_id; let med_name = item.medicine_name; let med_frequency = item.medicine_frequency; let med_prescription = item.doctor_prescription; let med_time = item.medicine_time; this.tableData.push({id: med_id, name: med_name, frequency: med_frequency, prescription: med_prescription, time: med_time}); });
However, I came across a type error indicating
Cannot read property 'push' of undefined
. I am not sure how this error came about and why it is undefined.
Therefore, I am unsure if the method of pushing the
reminderData
intotableData
is wrong since I have been getting the same error after many tries or how can I improve my code to make this work. Hope this gives a clearer picture and explanation on the issue I am facing.Quasar List Code Snippet:
<template> <q-page class="q-pa-md"> <q-list bordered> <q-item v-for="data in tableData" :key="data.id" v-ripple> <q-item-section top avatar> <q-avatar color="primary" text-color="white" icon="notification_important" /> </q-item-section> <q-item-section> <q-item-label>{{ data.name }}</q-item-label> <q-item-label caption>{{ data.prescription}}</q-item-label> </q-item-section> <q-item-section side> <div class="column"> <q-item-label class="row justify-end">{{ data.time }}</q-item-label> <q-item-label class="row justify-end" caption>{{ data.frequency }}</q-item-label> </div> </q-item-section> </q-item> </q-list> </q-page> </template>
Script Code Snippet:
<script> var scanResults = []; var reminderData = []; export default { data() { return { tableData: [ { id: null, name: null, frequency: null, prescription: null, time: null } ] } }, methods: { getReminder() { var documentClient = new AWS.DynamoDB.DocumentClient({apiVersion: "2012-08-10"}); var params = { TableName: "schedule", Select: "ALL_ATTRIBUTES" }; documentClient.scan(params, function(err, data) { if (err) { console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2)); } else { for(var i in data) { scanResults.push([i, data[i]]); } reminderData = scanResults[0]; reminderData = reminderData[1]; console.log("items!!" + JSON.stringify(reminderData, null, 2)); reminderData.forEach((item) => { let med_id = item.medicine_id; let med_name = item.medicine_name; let med_frequency = item.medicine_frequency; let med_prescription = item.doctor_prescription; let med_time = item.medicine_time; this.tableData.push({id: med_id, name: med_name, frequency: med_frequency, prescription: med_prescription, time: med_time}); }); } }); } } } </script>
-
@felice ty, your reference to
this
inside your aws function is not the same as your component’s context. Imho you should convert your methods to async await and return the result, then do the assignment after that. -
No need for async await.
In
getReminder()
replace:documentClient.scan(params, function(err, data) { ...
With:
documentClient.scan(params, (err, data) => { ...
The difference is, that in a function using the
function
keyword,this
has a different meaning as in a function using the arrow syntax.
You just discovered why arrow functions are so great – everything inside works as one would expectIf you are interested in more details, here is an article about it: https://medium.com/free-code-camp/learn-es6-the-dope-way-part-ii-arrow-functions-and-the-this-keyword-381ac7a32881#.59q9th108
That should solve your error. You’ll see, everything with the iteration and with how you are using .push() is fine.
-
I may have read your code incorrectly + I don’t know your wider use case but …
You could use original attribute names (e.g. medicine_frequency) instead of derived names (e.g. frequency) in your template.
This would negate need to map attribute names and allow you to update tableData by adding lists together (concat not push).
Your code would be simpler.
Something like
<script> export default { data() { return { scanResults: [], tableData: [] } }, methods: { getReminder() { var documentClient = new AWS.DynamoDB.DocumentClient({apiVersion: "2012-08-10"}); documentClient.scan({ TableName: "schedule", Select: "ALL_ATTRIBUTES" }, (err, data) => { if (err) { console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2)); } else { for(var i in data) { this.scanResults.push([i, data[i]]); } this.tableData.concat(scanResults[0][1]) } }); } } } </script>
-
@metalsadman @chyde90 Thank you for all the advices! I have tried using the arrow syntax and it’s now working fine with the error! I guess I have learnt a new thing today! Thank you so much, really appreciate the great help!!!
-
@rab oh I see! I will try to use this method as well! Thank you for your advices, really appreciate the help alot!
-
Hi @chyde90, I would like to enquire about the following issue:
As I want to auto-load the list of items when the page is refreshed, I have included the following code that runs the
getReminder
method when the page is loaded.created() { this.getReminder() if(this.credentials) { console.log("in created(), have credentials"); } else { console.log("in created(), getting credentials..."); this.credentials = this.getCredentials(); } }
However, I am getting the following error indicating that it cannot read the property ‘tableData’ of undefined which I don’t really understand what the error means.
I have made changes to the existing
getReminder
code by adding the credentials in:methods: { getReminder() { var documentClient = new AWS.DynamoDB.DocumentClient({apiVersion: "2012-08-10"}); var params = { TableName: "schedule", Select: "ALL_ATTRIBUTES" }; if(this.credentials) { documentClient.scan(params, (err, data) => { if (err) { console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2)); } else { for(var i in data) { scanResults.push([i, data[i]]); } reminderData = scanResults[0]; reminderData = reminderData[1]; reminderData.forEach((item) => { let med_id = item.medicine_id; let med_name = item.medicine_name; let med_frequency = item.medicine_frequency; let med_prescription = item.doctor_prescription; let med_time = item.medicine_time; this.tableData.push({id: med_id, name: med_name, frequency: med_frequency, prescription: med_prescription, time: med_time}); }); } }); } else { var that = this; var promise = AWS.config.credentials.getPromise(); promise.then( function() { var creds = { ... }; that.credentials = creds; documentClient.scan(params, (err, data) => { if (err) { console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2)); } else { for(var i in data) { scanResults.push([i, data[i]]); } reminderData = scanResults[0]; reminderData = reminderData[1]; reminderData.forEach((item) => { let med_id = item.medicine_id; let med_name = item.medicine_name; let med_frequency = item.medicine_frequency; let med_prescription = item.doctor_prescription; let med_time = item.medicine_time; this.tableData.push({id: med_id, name: med_name, frequency: med_frequency, prescription: med_prescription, time: med_time}); }); } }); }, function(err) { that.credentials = null; } ); }
-
-
@rab I managed to solved my error by the following amendments and it worked!
Thanks alot!
Instead of using:promise.then(function() {...});
I have changed to:
promise.then(() => {...});