How can I populate my data from an array in another method?



  • @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 into tableData above so that it can be reflected in the q-list

    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});
    });
    

    I think that the undefined error is due to it not being able to recognize the tableData 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 the tableData where each attribute is initialized to null. Also, a getReminder() method is created to retrieve all the data in the database and store them in the array - reminderData. I want to put every data in reminderData into tableData, hence I have tried using a forEach method to iterate through every data in the array, and the .push method for pushing the data into tableData.

    Results of reminderData printed in the console:
    c918d4a7-15f9-4cd5-a1de-c3c9696a6909-image.png

    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.
    cf36c9e9-5182-401a-991f-ab13c246e4b7-image.png

    Therefore, I am unsure if the method of pushing the reminderData into tableData 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 expect 🙂

    If 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.



  • @felice

    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.
    bb69c31e-4f25-42c4-890a-e45e2a0f30cc-image.png

    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(() => {...});
    

Log in to reply