Search code examples
javascriptreact-nativeparse-platform

I can't get data from query.find().then(function(results) it seems to be just local


I can't get flatListData because it seems to be local only I can get flatList data just inside query.find().then(function(results) And Outside that I got None!

I Try this with Async/Await either but doesn't work

const W = Parse.Object.extend("W");
const query = new Parse.Query(W);
var flatListData = [];

query.find().then(function(results) {
for (var i=0; i < results.length; i++){
flatListData.push(String(results[i].get("AlphabetCode")));
}

  alert(flatListData) //{"a" , "b" , "s" , "w"}

 });

 alert(flatListData) // Nothing! 
module.exports = flatListData;

Solution

  • The problem here is that you are trying to make an async export statement, which is strictly forbidden.

    First of all, yes, flatListData is global, not locally scoped. The actual issue you are facing is that, while your query result is effectively given to your variable, it takes some time as an async function to complete. When you call your variable in your second alert(), and in your module.exports, your async query hasn’t finished yet, so new value isn’t assigned and you end up sending nothing but undefined value to your outer script.

    Now the only possible way to deal with it is to force your module.exports to wait for the variable to be assigned, which means either scoping it inside your promise (along with your first alert()), or using an await statement. BUT :

    MDN Documentation

    The await operator is used to wait for a Promise. It can only be used inside an async function.

    So there it is. Your only exit path is to scope your module.exports… Which is totally forbidden. You never want to call your exports apart from top level, aka global scope.

    Redefine the problem

    Your goal is to export a content set in your object, to be used from many places.

    But keep in mind that you cannot export anything asynchronously. In your case, your only choice would be to export a function, and call it whenever you need your value.

    Now the solution

    getFlatListData.js, or whatever you called it

    // Those are globally scoped. They will only be calculated on
    // initialization, and not during outside import calls
    const W = Parse.Object.extend("W");
    const query = new Parse.Query(W);
    
    // We wrap everything inside an async function, which will be exported
    function getFlatListData() {
      // We return a promise, to allow outer calls to the result
      return new Promise(resolve => {
        // Also, avoid var. If you need a variable which isn’t constant, prefer let.
        let flatListData = [];
    
        // Prefer arrow functions here
        query.find().then(results => {
          // Works like your classic for(…) loop, but more efficient
          for(const result of results) {
            flatListData.push(String(result.get("AlphabetCode")));
          }
    
          // Resolve your function and send the result back
          resolve(flatListData);
        });
      });
    }
    
    module.exports = getFlatListData;
    

    And now, in your outside script :

    main.js, or whatever

    // Assuming you are using commonJS syntax
    const getFlatListData = require(‘path_to_your_script/getFlatListData’);
    
    [. . .]
    
    getFlatListData().then(result => {
      // Now you can use your FlatListData aliased as result
    });
    
    // OR
    
    const myAsyncFunction = async() => {
      const myVariable = await getFlatListData();
    
      // Use myVariable as you please now
    };
    

    Lot of improvements can be done here, such as using a map() function to assign your flatListData, or adding a reject to your promise to handle any errors. But you got the main idea.

    Never make asynchronous exports, and if you have to do so, it means you need to rethink about your code !