2013-08-14 21 views
7

Mi chiedo come simulare una promessa $ http quando so che la richiesta non riuscirà sul lato server. Ecco il mio codice:AngularJS Promises - Simula le promesse 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

Do promise.reject() invece di $ q.reject(); –

+0

Viene visualizzato il seguente errore: L'oggetto n. non ha il metodo 'rifiutare' – Frank6

+0

il controllo di isString ha qualcosa a che fare con la funzione $ http dopo? Si prega di semplificare il riferimento – nXqd

risposta

5

Ok, ho potuto capire come simulare la stessa promessa restituita dall'oggetto $ http. Grazie a tutti per le vostre risposte. Potrei prenderli tutti in considerazione. Qui è la mia soluzione:

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

Mi chiedo perché i metodi' success' e 'error' non siano già definiti in una promessa. Sembra che sarebbe utile non pensate? – Frank6

+1

Avevo bisogno di fare qualcosa del genere. La mia soluzione è simile, ma ho pensato di far notare che 'promise.then (function (response) {fn (response);})' è effettivamente la stessa cosa di 'promise.then (fn)'. –

0

La sintassi è un po 'incasinata. Prova a modificare:

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

Grazie per la tua risposta! Ma poiché ho bisogno di essere in grado di usare il metodo 'success' e' error' invece di 'then', ottengo il seguente errore: L'oggetto # non ha alcun metodo 'successo' – Frank6

+0

Combattere le diverse interfacce di promessa tra HttpPromise e Promise –

5

È possibile utilizzare determinazione e respingere per controllare il flusso dei dati:

Diciamo che avere un servizio come questo:

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; 
    } 
    }; 
}]); 

Il servizio può quindi essere utilizzato come tale:

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; 
    }); 
}]); 

È possibile gestire l'errore nella seconda richiamata.

+0

Grazie per la tua risposta!Sembra buono ma ho bisogno di essere in grado di usare il metodo 'success' e' error' invece di 'then' – Frank6

+0

Le promesse che' $ q' offre in angolare non hanno quei metodi fuori dalla scatola, ho suggerito di modificarli qui: http://stackoverflow.com/questions/17686612/rejecting-promises-with-multiple-arguments-like-http-in-angularjs/17687321#17687321 – Florian

1

Qualcosa del genere dovrebbe funzionare:

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

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

poi nel codice lo usano come una promessa regolare

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

Grazie per la risposta! Sembra buono anche se devo usare il metodo 'success' e' error' invece di 'then' ... – Frank6

3

Il $http cambio una promessa nel angularJS. Si può fare in questo modo:

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

si può cercare il successo e funzioni di errore in jQuery chiamata AJAX ma è cosa diversa che lavora qui in angularJS. Potrebbe essere necessario seguirlo per farlo funzionare correttamente.

Puoi dirci di più sul motivo per cui è necessario utilizzare il successo e l'errore in modo che possiamo trovare un modo per farlo funzionare con il tuo caso.

1

Giocando con il suo suggerimento di sotto (e il debug del codice Angularjs), ho trovato un modo più semplice, che permette di rifiutare o risolvere.

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(...); 
} 

(sia success e error metodi restituiscono this per consentire callback accodato)

Problemi correlati