0

Im using this plugin: http://www.codingdrama.com/bootstrap-markdown/

I want to hook the onPreview

So on onPreview i try to make my api call:

   app.directive("markdowntextarea",function ($http, $q) { // inject $q
    return {
        link: function (el_scope, element, attr) {
            element.markdown(
                {
                    autofocus: false,
                    savable: false,
                    onPreview: function (e) {
                        var deferred = $q.defer();
                        if (e.isDirty()) {
                            var originalContent = e.getContent();
                            $http({
                                url: '/api/markdown/',
                                data: {"body": originalContent, "actual_format": "md"},
                                method: 'POST'
                            }).then(function successCallback(response) {
                                console.log("successCallback", response.data.content);
                                deferred.resolve(response.data.content);
                            }, function errorCallback(response) {
                                console.log("errorCallback");
                                deferred.reject("error");
                            });
                        } else {
                            deferred.resolve("");
                        }
                        return deferred.promise;
                    }
                }
            );
        }
    }
});

Console:

successCallback from api!!!

I got success response from api, the response.data.content is what I want to use. The problem here is the return deferred.promise; always return the original value. What can I do here? I'm really new in angularjs

62009030
  • 347
  • 1
  • 5
  • 20

2 Answers2

1

With promises you can't return values at once, usually you return promise object called promise handle and using 'then' clause you wait for promise to resolve(successfully) or reject(failure).

In your case if you want to wait for response and then do something I suggest you call onPreview and use its then clause like:

onPreview(e).then(function(response){}, function(error){});

onPreview is already returning promise which should be thenable.

After Edit:

So onPreview is API method and is expecting a text not promise, now what you can do is define a function like makePreview or something:

function makePreview(e) {
    var deferred = $q.defer();
    if (e.isDirty()) {
        var originalContent = e.getContent();
        $http({
            url: '/api/markdown/',
            data: {"body": originalContent, "actual_format": "md"},
            method: 'POST'
        }).then(function successCallback(response) {
            console.log("successCallback", response.data.content);
            deferred.resolve(response.config.data.body);
        }, function errorCallback(response) {
            console.log("errorCallback");
            deferred.reject("error");
        });
    } else {
        deferred.resolve("");
    }
    return deferred.promise;
}

and then your onPreview should look like this:

autofocus: false,
savable: false,
onPreview: function (e) {
    makePreview(e).then(function(response){
        e.setContent(response);
        return response;
    }, function(error){
        return error;
    });
}

I hope this helps :)

user2009750
  • 3,169
  • 5
  • 35
  • 58
  • Hi, I edited the question. Could you tke a look? thanks – 62009030 Feb 21 '17 at 14:18
  • hi, thanks. a noob question. the new function should be also inside the app.directive("markdowntextarea",function ($http, $q) { – 62009030 Feb 21 '17 at 14:32
  • if yes, I still got the original str, not the content from api call – 62009030 Feb 21 '17 at 14:35
  • Sorry for so many questions, is first time time I use Angular, also I have to finish this task today . – 62009030 Feb 21 '17 at 14:38
  • Yes and are you sure `response.data.content` contains correct values? you might want to debug the resolve statements from your browser developer tools – user2009750 Feb 21 '17 at 14:38
  • Yes. I got this on console :successCallback--------------> from API!!! (is from the success call . Is that str I need – 62009030 Feb 21 '17 at 14:41
  • try changing this `deferred.resolve(response.data.content);` to `deferred.resolve('testing content');` and see if you get testing content as your new content also try console.log(response); to see which property in response contains the new content you look for and then pass that into deferred.resolve – user2009750 Feb 21 '17 at 14:44
  • I still got the originalContent – 62009030 Feb 21 '17 at 14:48
  • console.log(response); -> Object config : Object data : Object content : "from api!!!" – 62009030 Feb 21 '17 at 14:50
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/136259/discussion-between---and-62009030). – user2009750 Feb 21 '17 at 14:52
  • I have a last question. can you go to chat? – 62009030 Feb 21 '17 at 15:44
0

You cannot write angular in absolute sync way. Use the response in callback. If you need to control api requests' order, or wait for multiple requests, see doc of $q

Valens
  • 164
  • 3