1

I'm currently using a factory called http that when I invoke it, I make a web request. this receives as a parameter the url of the web request.

app.factory('http', function ($http) {
 var oHttp = {}
 oHttp.getData= function (url) {

    var config={
        method: 'GET',
        url: url
    }
    return $http(config).then(function(data) {
        oHttp.data=data.data;
    },function(response) {
       alert("problem, can you trying later please?")
    });
  }
 return oHttp;

});


function HelloCtrl($scope, http) {
 http.getData('https://www.reddit.com/.json1').then(function(){
  if(http.data!=undefined){
   console.log(http.data)
  }
 })
}

I would like the promise not to be executed on the controller if the result of the web request is not satisfied or there is a problem. is there any better solution? I want to avoid doing this every time I make a web request, or do not know if it is the best way (see the if):

//I am putting "1" to the end of the url to generate an error.
  http.getData('https://www.reddit.com/.json1').then(function(){
   //validate that the result of the request != undefined
    if(http.data!=undefined){
     alert(http.data.kind)
    }
  })

In my real project I make n web requests using my factory http, I do not want to do this validation always. I do not know if I always have to do it or there is another solution.

this is my code:

https://plnkr.co/edit/8ZqsgcUIzLAaI9Vd2awR?p=preview

unusuario
  • 151
  • 1
  • 13
  • A promise is not "executed". Do you mean the http request or the promise callback that you don't want to execute? – Bergi Oct 22 '17 at 10:17
  • possible duplicate of https://stackoverflow.com/questions/16371129/chained-promises-not-passing-on-rejection – Bergi Oct 23 '17 at 11:24

3 Answers3

0

In Service

app.factory('http', function ($http) {
     var oHttp = {}
     oHttp.getData= function () {
        return $http({
        method: 'GET',
        url: 'https://www.reddit.com/.json1'
        });
      }
     return oHttp;

    });

In controller

function HelloCtrl($scope, http) {
   var httpPromise = http.getData();
   httpPromise.then(function(response){
      console.log(response);
   });
   httpPromise.error(function(){
   })
}
byteC0de
  • 5,153
  • 5
  • 33
  • 66
  • thanks, I think you forgot the URL parameter. but it would practically be the same result, there may be an error in the request and it would return to the point of the question because equal access to the promise from the controller – unusuario Oct 22 '17 at 05:50
  • Url, not a parameter, you need to add it from service pls see the edit – byteC0de Oct 22 '17 at 05:57
  • Beautifully cleaned up there, but wasn't the goal of the question about checking IF the data returned was undefined and how to check that within the service rather than manually every time you called the service. Or if the request is successful but response.data is undefined does it run the httpPromise.error()? Or is it just something you have to live with. – Pocketninja Oct 22 '17 at 06:25
  • You need to handle it in your server-side scripting – byteC0de Oct 22 '17 at 07:10
0

So I tried this in codepen having ripped your code out of plinkr

https://codepen.io/PocketNinjaDesign/pen/oGOeYe

The code wouldn't work at all...But I changed the function HelloCtrl to a controller and it seemed happier....?

I also set response.data to default to an empty object as well. So that way if you're populating the data in the page it will be empty if nothing arrived. You can then in some instances on the site check the length if it's really required.

app.factory('http', function ($http) {
  var oHttp = {}
  oHttp.data = {};

  oHttp.getData= function (url) {
    var config = {
      method: 'GET',
      url: url
    }
    return $http(config).then(function(response) {
      oHttp.data = response.data || {};
    }, function(response) {
      alert("problem, can you trying later please?")
    });
  }
  return oHttp;
});

app.controller('HelloCtrl', function($scope, http) {
  http.getData('https://www.reddit.com/.json').then(function(){
    alert(http.data.kind);
  })
});
Pocketninja
  • 395
  • 1
  • 12
0

In rejection handlers it is important to re-throw the error response. Otherwise the rejected promise is converted to a successful promise:

app.factory('http', function ($http) {
 var oHttp= {};
 oHttp.getData= function (url) {

    var config={
        method: 'GET',
        url: url
    }
    return $http(config).then(function(response) {
        ̶o̶H̶t̶t̶p̶.̶d̶a̶t̶a̶=̶r̶e̶s̶p̶o̶n̶s̶e̶.̶d̶a̶t̶a̶;̶
       return response.data;
    },function(response) {
       alert("problem, can you trying later please?")
       //IMPORTANT re-throw error
       throw response;
    });
  }
 return oHttp;

});

In the controller:

 http.getData('https://www.reddit.com/.json1')
   .then(function(data){    
      console(data)
 }).catch(response) {
      console.log("ERROR: ", response.status);
 });

For more information, see You're Missing the Point of Promises.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • for what is throw response? – unusuario Oct 23 '17 at 14:57
  • When a function in a [promise chain](https://docs.angularjs.org/api/ng/service/$q#chaining-promises) uses a [throw statement](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw), the exception bypasses all subsequent `.then` blocks and gets caught by the next `.catch` block. This behavior mimics the behavior of the [try...catch](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch) statements of synchronous JavaScript. – georgeawg Oct 23 '17 at 23:03