2013-08-14 18 views
7

Zastanawiam się, jak zasymulować obietnicę $ http, gdy wiem, że żądanie zakończy się niepowodzeniem po stronie serwera. Oto mój kod:Obietnice AngularJS - Symulacja obietnicy http

if (!ng.isString(email)) { 
    var promise = $q.defer().promise; 
    $q.reject(); 

    return promise; 
} 

return $http({ 
     method : "PUT", 
     url : "//localhost/update" , 
     data : { data: email } 
}) 

// Success handler 
.success(response){ return response}) 

// Error handler 
.error(errorMsg){ return errorMsg}); 
+1

Czy promise.reject() zamiast $ q.reject(); –

+0

Pojawia się następujący błąd: Obiekt nr nie ma metody "odrzuć" – Frank6

+0

czy sprawdzenie dla isString ma coś wspólnego z funkcją $ http po tym? Uprośnij swój numer referencyjny – nXqd

Odpowiedz

5

Ok, mógłbym wymyślić jak zasymulować tę samą obietnicę zwróconą przez obiekt $ http. Dziękuję wszystkim za twoje odpowiedzi. Mógłbym wziąć je wszystkie pod uwagę. Oto moje rozwiązanie:

if (!ng.isString(email)) { 

    // We need to create a promise like the one returned by the 
    // $http object (with the success and error methods) 
    // to stay consistent. 
    var promise = $q.reject("error with email"); 

    // Defining success and error method for callbacks. 
    // but it should never be called since the promise 
    // is already rejected. 
    promise.success = function(fn){ 
     promise.then(function(response){ 
      fn(response) 
     }, null); 
      return promise 
    }; 

    promise.error = function(fn){ 
     promise.then(null, function(response){ 
      fn(response) 
     }); 
     return promise; 
    }; 

    return promise; 
} 

return $http({ 
     method : "PUT", 
     url : "//localhost/update" , 
     data : { data: email } 
}) 

// Success handler 
.success(response){ return response}) 

// Error handler 
.error(errorMsg){ return errorMsg}); 
+1

Zastanawiam się, dlaczego metody" sukcesu "i" błędu "nie są już zdefiniowane w obietnicy. Wygląda na to, że byłoby to przydatne, nie myślicie? – Frank6

+1

Potrzebowałem zrobić coś takiego. Moje rozwiązanie jest podobne, ale pomyślałem, że zwrócę uwagę, że 'promise.then (function (response) {fn (response);})' jest efektywnie taki sam jak "promise.then (fn)". –

0

Twoja składnia jest trochę pomieszana. Spróbuj to zamiast:

var deferred = $q.defer(); 
$q.reject(); 
return deferred.promise; 
+0

Dzięki za odpowiedź! Ale z powodu konieczności użycia metody 'success' i' error' zamiast 'then', pojawia się następujący błąd: Obiekt nr nie ma metody 'sukces' – Frank6

+0

Walka z różnymi interfejsami obietnic między HttpPromise i Promise –

5

Można użyć determinację i odrzucić kontrolować przepływ danych:

Powiedzmy masz usługę tak:

var app = angular.module("mymodule.services", []); 

app.factory("HttpRequest", ['$q', '$http', function(q, http) { 
    var deferredData = q.defer(); 

    http.get('http://your-server.local/data.json').success(function(data) { 
    //success, resolve your promise here 
    deferredData.resolve(data); 
    }).error(function(err) { 
    //error, use reject here 
    deferredData.reject(err); 
    }); 

    return { 
    get: function() { 
     return deferredData.promise; 
    } 
    }; 
}]); 

Usługa może być następnie używany jako taki:

var app = angular.module("mymodule.controllers", ['mymodule.services']); 

app.controller("MyCtrl", ['HttpRequest', '$scope', function(res, scope) { 
    //the "then"-method of promises takes two functions as arguments, a success and an erro callback 
    res.get().then(function(data) { 
    //first one is the success callback 
    scope.data = data; 
    }, 
    function(err) { 
    scope.err = err; 
    }); 
}]); 

Możesz obsłużyć błąd w drugim oddzwonieniu.

+0

Dzięki za odpowiedź!Brzmi nieźle, ale muszę umieć użyć metody 'sukcesu' i' błędu' zamiast 'then' – Frank6

+0

Obietnice, że' $ q' oferuje kątowe, nie mają tych metod po wyjęciu z pudełka, sugerowałem ich modyfikację tutaj: http://stackoverflow.com/questions/17686612/rejecting-promises-with-multiple-arguments-like-http-in-angularjs/17687321#17687321 – Florian

1

Coś jak to powinno działać:

if (!ng.isString(email)) 
    return $q.reject("Email is invalid."); // returns rejected promise 

return $http({ 
     method : "PUT", 
     url : "//localhost/update" , 
     data : { data: email } 
}); 

następnie w kodzie używać go jako zwykłej obietnicy

mypromise.then(function(x) { do something with x.data }, function(error) { alert(error)}); 
+0

Dzięki za odpowiedź! Brzmi nieźle, ale muszę umieć używać metody 'sukcesu' i' błędu' zamiast 'then' ... – Frank6

3

$http powrotnej obietnica w angularjs. Można to zrobić tak:

var promise = $http(...) ; 
promise.then(function(data) {}, function(error){}); 

Można spojrzeć na sukces i funkcja błędu w jQuery wywołanie ajax, ale to inna sprawa, że ​​działa tutaj w angularjs. Być może będziesz musiał postępować zgodnie z nim, aby działał poprawnie.

Możesz nam powiedzieć więcej o przyczynie, dla której musisz użyć sukcesu i błędu, abyśmy mogli znaleźć sposób, aby zadziałał on w Twojej sprawie.

1

Bawiąc się z poniższym sugestię (i debugowania angularjs kod), znalazłem bardziej uproszczony sposób, który pozwala, aby odrzucić lub rozwiązać.

if (alreadyLoaded){ 
    var defered = $q.defer(); 
    defered.success = function(fn){ 
     defered.promise.then(fn); 
     return defered; 
    }; 
    defered.error = function(fn){ 
     defered.promise.then(null, fn);//or defered.promise.catch(fn) 
     return defered; 
    }; 
    if(data.invalid) 
     defered.reject("arbitrary error"); 
    else 
     defered.resolve(data); 
    return defered; 
}else { 
    return $http.get(...); 
} 

(zarówno success i error metody powrotu this aby umożliwić skolejkowany zwrotnych)

Powiązane problemy