2015-12-07 2 views
1

Я пытаюсь работать с Parse Cloud Code и использовать обещания, чтобы убедиться, что я устраняю любые проблемы с asals. Я хочу запросить класс, вернуть объект, создать JSON, затем запросить некоторые отношения объекта (теги, рефери) и добавить их в JSON, чтобы вернуться для ExpressJS для рендеринга. Код, который я вставляю, не работает, но я не понимаю, почему, если каждый раз я возвращаюсь к проекту для следующего обещания по запросу.Проблемы с Parse Cloud Code Promises

Edit:

//Return a single project 
Parse.Cloud.define('getProject', function(request, response) { 
    var projectUrl = request.params.projectUrl; 

    var project; 
    var projectsData = []; 

    var Projects = new Parse.Object("projects"); 
    var query = new Parse.Query(Projects); 
    query.equalTo("projectUrl", projectUrl); 
    query.find().then(function(projectsResult) { 
     console.log(projectsResult.length + " Projects returned"); 

     project = projectsResult[0]; 
     var projectData = { 
      "id": project.get("id"), 
      "title": project.get("title"), 
      "previewImage": project.get("previewImage"), 
      "longDescription": project.get("longDescription"), 
      "shortDescription": project.get("shortDescription"), 
      "visibleToPublic": project.get("visibleToPublic"), 
      "dateStart": project.get("dateStart"), 
      "dateEnd": project.get("dateEnd"), 
      updatedAt: project.get("updatedAt"), 
      projectStatus: project.get("projectStatus") 
     }; 

     projectsData.push(projectData); 
     console.log("Step 1. Projects Data: " + JSON.stringify(projectsData)); 

     var tagsQuery = project.relation('tags'); 
     return tagsQuery.query().find(); 
    }).then(function(tags) { 
     var tagsData = []; 
     for(var t = 0; t < tags.length; t++) { 
      var tagData = { 
       "tag": tags[t].get("tag"), 
      } 
      console.log("Tag Data: " + tagData); 
      tagsData.push(tagData); 
     } 
     projectsData[tags] = tagsData; 
     console.log("Step 2. Tags Data: " + JSON.stringify(tagsData)); 

     var refereesQuery = project.relation('referees'); 
     return refereesQuery.query().find(); 
    }).then(function(referees) { 
     var refereesData = []; 
     for(var r = 0; r < referees.length; r++) { 
      var refereeData = { 
       "name": referees[r].get("name"), 
       "role": referees[r].get("role"), 
       "emailAddress": referees[r].get("emailAddress"), 
       "phoneNumber": referees[r].get("phoneNumber"), 
       "linkedInUrl": referees[r].get("linkedInUrl"), 
      } 
      console.log("Referee Data: " + refereeData); 
      refereesData.push(refereeData); 
     } 
     projectsData[referees] = refereesData; 
     console.log("Step 3. Referees Data: " + JSON.stringify(refereesData)); 

     console.log("Everthing should be part of Projects Data here: " + JSON.stringify(projectsData)); 

     response.success(projectsData); 
    }, function(error) { 
     response.error("Error: " + error); 
    }); 
}); 

ответ

0

Есть несколько вопросов:

  • Путаница между projectsData и projectData
  • projectsData не является на самом деле необходимо.
  • projectData должен быть в объеме в трех местах, которые он (или должен быть) использован после его создания. & назначено.
  • В некоторых случаях .then() используется там, где достаточно стандартного синхронного потока. Очистка ненужных .thens поможет значительно разобраться в проблемах области.

Делать немного больше, чем перетасовка код вокруг, я прихожу к следующему:

Parse.Cloud.define('getProject', function(request, response) { 
    var Projects = Parse.Object.extend("projects"); // with credit to @kRiZ 
    var query = new Parse.Query(Projects); 
    query.equalTo('projectUrl', request.params.projectUrl); 
    query.find().then(function(projectsResult) { 
     var project = projectsResult[0]; 
     var projectData = { 
      'id': project.get('id'), 
      'title': project.get('title'), 
      'previewImage': project.get('previewImage'), 
      'longDescription': project.get('longDescription'), 
      'shortDescription': project.get('shortDescription'), 
      'visibleToPublic': project.get('visibleToPublic'), 
      'dateStart': project.get('dateStart'), 
      'dateEnd': project.get('dateEnd'), 
      'updatedAt': project.get('updatedAt'), 
      'projectStatus': project.get('projectStatus') 
     }; 

     //Now make the tags query and the referees query in parallel. 
     var tagsPromise = project.relation('tags').query().find(); 
     var refereesPromise = project.relation('referees').query().find(); 

     // Aggregate the two promises with Parse.Promise.when(), and handle the responses. 
     return Parse.Promise.when(tagsPromise, refereesPromise).then(function(tags, referees) { 
      //Process the tags response 
      projectData.tags = tags.map(function(t) { 
       return { 
        'tag': t.get('tag') 
       }; 
      }); 
      //Process the referees response 
      projectData.referees = referees.map(function(r) { 
       return { 
        'name': r.get('name'), 
        'role': r.get('role'), 
        'emailAddress': r.get('emailAddress'), 
        'phoneNumber': r.get('phoneNumber'), 
        'linkedInUrl': r.get('linkedInUrl') 
       }; 
      }); 
      // Yay! 
      response.success(projectData); 
     }); 
    }).fail(function(error) { 
     response.error('Error: ' + error); 
    }); 
}); 

Помимо общей перестройки, только существенные изменения:

  • Использование Array#map() для сопоставления массива с другим массивом.
  • Выполнение двух запросов параллельно и с использованием Parse.Promise.when() для объединения двух обещаний.
+0

Это работало фантазивно @ Роамер-1888. Теперь мне просто нужно выяснить, как запросить другой класс и добавить к моему наращиванию данные/ –

+0

Марк, если третий запрос зависит только от 'prom', тогда мой шаблон должен хорошо расширяться для его размещения. Просто добавьте еще один оператор 'var xxxxPromise = project.relation ...', добавьте' xxxxPromise' в 'Parse.Promise.when (...)' и обработайте ответ тем же способом, что и теги '' и ' referees'. –

+0

Итак, я думаю, что я последовал твоим советам, но не получил население, на которое я надеялся. Я также попытался связать обещание запросить глубже, то есть Но это тоже не сработало. Я обновил свой код по следующему вопросу http://stackoverflow.com/questions/34146245/returning-deeper-relations-in-parse-cloud-code-when-using-promises –

0

Проблема, как представляется, с первоначальным запросом. Вы пытаетесь использовать подклассы, но ваш синтаксис неверен.

Ваш запрос должен начинаться так:

var Projects = Parse.Object.extend("projects"); 
var query = new Parse.Query(Projects); 

EDIT:

Кроме того, вы возвращаете объекты, вы должны вернуть обещания. См ниже код (не проверено):

Parse.Cloud.define('getProject', function(request, response) { 
    var projectUrl = request.params.projectUrl; 
    var projectsData = []; 

    var Projects = Parse.Object.extend("projects"); 
    var query = new Parse.Query(Projects); 
    query.equalTo("projectUrl", projectUrl); 
    query.find().then(function(projectsResult) { 
     console.log(projectsResult.length + " Projects returned"); 

     var project = projectsResult[0]; 
     var projectData = { 
      "id": project.get("id"), 
      "title": project.get("title"), 
      "previewImage": project.get("previewImage"), 
      "longDescription": project.get("longDescription"), 
      "shortDescription": project.get("shortDescription"), 
      "visibleToPublic": project.get("visibleToPublic"), 
      "dateStart": project.get("dateStart"), 
      "dateEnd": project.get("dateEnd"), 
      updatedAt: project.get("updatedAt"), 
      projectStatus: project.get("projectStatus") 
     }; 

     projectsData.push(projectData); 
     console.log("Step 1. Projects Data: " + JSON.stringify(projectsData)); 

     // Removed the return from here 

     var tagsData = []; 
     console.log("Project Step 2: " + JSON.stringify(project)); 
     var tagsQuery = project.relation('tags'); 
     return tagsQuery.query().find(); 
    }).then(function(tags) { 
     for(var t = 0; t < tags.length; t++) { 
      var tagData = { 
       "tag": tags[t].get("tag"), 
      } 
      tagsData.push(tagData); 
     } 
     projectsData.tags = tagsData; 
     console.log("Step 2. Tags Data: " + JSON.stringify(tagsData)); 

     // Removed return from here 

     var refereesData = []; 
     var refereesQuery = project.relation('referees'); 
     return refereesQuery.find(); 
    }).then(function(referees) { 
     for(var r = 0; r < referees.length; r++) { 
      var refereeData = { 
       "name": referees[r].get("name"), 
       "role": referees[r].get("role"), 
       "emailAddress": referees[r].get("emailAddress"), 
       "phoneNumber": referees[r].get("phoneNumber"), 
       "linkedInUrl": referees[r].get("linkedInUrl"), 
      } 
      refereesData.push(refereeData); 
     } 
     projectData.referees =refereesData; 
     console.log("Step 3. Referees Data: " + JSON.stringify(refereesData)); 

     response.success(projectsData); 
    }, function(error) { 
     response.error("Error: " + error); 
    }); 
}); 

См Анализировать документацию here на получение данных с помощью подклассов.

+1

Это EXTREMELY разочаровывает, когда все последние новости о Parse Cloud Code говорят о том, как использовать Promises, но вся документация использует обратный вызов. Это смешанное сообщение и затрудняет поиск полезных примеров. Я изменил код выше, но все еще не работает. Ошибка, которую я получаю: ' Результат: TypeError: Невозможно вызвать метод 'отношение' неопределенного ' –

+1

Да, их документация не обновляется. Ошибка хорошая, это означает, что ваши обещания работают. Ошибка означает, что ваш объект имеет значение null (undefined). – kRiZ

+0

См. Обновление выше.Вы возвращали фактические объекты, должны возвращать обещания. Однако код непроверен, но должен дать общее представление. – kRiZ