Vietnam

    Nodejs.vn

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Popular
    • Tags
    • Groups
    • Search

    Hỏi cách return value trong factory trong angularjs?

    AngularJS
    3
    7
    4264
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Chí Nguyễn Thiện
      Chí Nguyễn Thiện Angel last edited by Lê Mạnh Hùng

      Mình có 1 factory như sau:

      app.factory('getApiUrl', function (http, $q) {
          var obj = {};
          obj.getResponse = function (url) {
              var promise = $q.defer();
      
              httpq.get(url).then(function (data) {
                  //obj = data.data;
                  promise.resolve(data.data);
              });
              return promise.promise;
          }
          return obj;
      });
      

      giờ mình muốn xài cái factory này, trong controller mình viết
      var test=getApiUrl.getResponse (url);
      nhưng không thể gán giá trị cho hàm này được.

      1 Reply Last reply Reply Quote 0
      • mike
        mike last edited by

        Bạn đang dùng promise không đúng cách rồi. Anw, bạn giải thích cụ thể câu hỏi của bạn hơn được không?

        Chí Nguyễn Thiện 1 Reply Last reply Reply Quote 0
        • Ngoc Nguyen
          Ngoc Nguyen last edited by Ngoc Nguyen

          Vì method httpq.get(url) là một method async, do đó nếu để lệnh return promise.promise sau nó thì lệnh này có thể sẽ được chạy trước khi method httpq.get(url) được thực thi xong. Do đó câu lệnh return phải được viết trong hàm callback của method httpq.get(url), tức được viết trong then. Bạn có thể viết lại như sau:

          app.factory('getApiUrl', function (http, $q) {
              var obj = {};
              obj.getResponse = function (url) {
                  var promise = $q.defer();
                  return httpq.get(url).then(function (data) {
                      //obj = data.data;
                      return promise.resolve(data.data);
                  });
              }
              return obj;
          });
          

          Method getResonse sẽ trả về một promise. Để sử dụng được giá trị trả về khi promise này được fulfill thành công bạn có thể gọi như sau:

          getApiUrl.getResponse(url).then(function (data) {
             // Do something with data
          });
          

          Tuy nhiên bản thân method httpq.get(url) đã trả về là một promise rồi nên bạn không cần phải tạo thêm một promise nữa. Ngắn gọn hơn sẽ là:

          app.factory('getApiUrl', function (http, $q) {
              var obj = {};
              obj.getResponse = httpq.get;
              return obj;
          });
          

          Còn cách gọi thì vẫn như bên trên:

          getApiUrl.getResponse(url).then(function (data) {
             // Do something with data
          });
          

          Không biết mình có hiểu đúng ý bạn không.

          1 Reply Last reply Reply Quote 1
          • Chí Nguyễn Thiện
            Chí Nguyễn Thiện Angel last edited by Chí Nguyễn Thiện

            Cảm ơn bạn đã giải thích cho mình hiểu rõ, có điều mình muốn hỏi thêm về work flow chương trình chút, vd chương trình mình lấy list danh sách từ 2 nguồn web api về, rồi mình muốn so sánh giữa 2 list hoặc gộp 2 list lại với nhau, như vậy thì khi mình gọi hàm , mình không thể dùng hàm gộp được, có cách nào xử lý không bạn. Mình cảm ơn bạn nhiều.

            Mình có thử viết lại theo cách gắn gọn của bạn :

            app.factory('getApiUrl', function (http, $q) {
            var obj = {};
            obj.getResponse = httpq.get(url).then(function (data) {});
            return obj;
            });
            tuy nhiên hàm không chạy được, bạn co thể trợ giúp mình phần này chút được kông bạn

            1 Reply Last reply Reply Quote 0
            • Chí Nguyễn Thiện
              Chí Nguyễn Thiện Angel @mike last edited by

              @rikky À, vì mình tínhxử lý data cho cả 2 cái web api, cho nên nhất thiết mình phải gán được dữ liệu vào biến, sau đó dùng biến đó để xử lý rồi mới đổ ra lại giao diện, cho nên mình muốn tìm cách nào để thực hiện

              1 Reply Last reply Reply Quote 0
              • Ngoc Nguyen
                Ngoc Nguyen last edited by

                Vì Angular sử dụng thư viện promise Q nên bạn có thể sử dụng hàm Q.all để làm được điều như bạn muốn, ví dụ:

                Q.all([getFromDisk(), getFromCloud()]).done(function (values) {
                    assert(values[0] === values[1]); // values[0] is fromDisk and values[1] is fromCloud
                });
                

                Trong đó getFromDisk() và getFromCloud() là các hàm async trả về các promise, Q.all nhận đối số là một mảng các promise, khi tất cả các promise này được fulfill xong thì hàm nested trong done sẽ được thực thi. Bạn có thể làm tương tự với ứng dụng bạn đang trong làm.

                1 Reply Last reply Reply Quote 1
                • H
                  hoocat Espresso last edited by

                  Bạn có thể yham khảo cái này:

                  app.factory('setDefault', function($http, $q) {
                  return {
                  getLocation: function() {
                  var def = $q.defer();
                  $http.post("/admin/callAPI", {
                  link: "/locations/list",
                  method: "GET"
                  })
                  .success( function (data) {
                  if (data.response.locations) {
                  for (var i = 0; i < data.response.locations.length; i++) {
                  if(data.response.locations[i].address && data.response.locations[i].address.line) {
                  var line = data.response.locations[i].address.line;
                  var lineSplit = line.split(' ');
                  if (lineSplit[0].match(/^-?\d+$/)) {
                  data.response.locations[i].streetName = lineSplit[1];
                  }else {
                  data.response.locations[i].streetName = lineSplit[0];
                  }
                  }
                  }

                              }
                              def.resolve(data.response.locations); 
                          })
                          .error( function(error){
                              def.resolve(error);
                          });
                          return def.promise;   
                      },
                      getSubCategory: function() {
                          var def = $q.defer();
                          $http.get("/admin/globalData?item=lSubCategory")
                          .success( function (data) {
                              def.resolve(data); 
                          })
                          .error( function(error){
                              def.resolve(error);
                          });
                          return def.promise; 
                      },
                      getCategory: function() {
                          var def = $q.defer();
                          $http.get("/admin/globalData?item=lCategory")
                          .success( function (data) {
                              def.resolve(data); 
                          })
                          .error( function(error){
                              def.resolve(error);
                          });
                          return def.promise; 
                      },
                  
                  };
                  

                  });

                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post
                  $(document).ready(function () { app.coldLoad(); }); }