1

i'm really new on angular. Im using angular 1.6, and i need to do some changes on a existing app.

As i could search, the previous developer was using http://www.codingdrama.com/bootstrap-markdown/ to have a textarea with some text options and a preview. My task now is to override the preview button to call our API with the text inserted and API return some result. On docs of that markdown I added up I found this.

onPreview: function(e) { var previewContent

if (e.isDirty()) {
  var originalContent = e.getContent()

  previewContent = "Prepended text here..."
         + "\n"
         + originalContent
         + "\n"
         +"Apended text here..."
} else {
  previewContent = "Default content"
}

return previewContent

},

So i started to override that:

   app.directive("markdowntextarea", ['$http', function ($http) {
    return {
        link: function (el_scope, element, attr) {
            var previewContent = "preview";
            element.markdown(
                {
                    autofocus: false,
                    savable: false,

                    onPreview: function (e) {
                        console.log('1');
                        if (e.isDirty()) {
                            console.log('2!!')
                            var originalContent = e.getContent();
                            $http({
                                url: '/api/markdown/',
                                data: {"body": originalContent, "actual_format": "md", "desire_format": "html"},
                                method: 'POST'
                            }).then(function successCallback(response) {
                                console.log(response.data.content);
                                previewContent = response.data.content;
                            });
                        }else{
                            console.log('3')
                            previewContent = "";
                        }
                        previewContent = 'test';
                       return previewContent;
                    },
                });
        }
    }
}]);

I can't find the error I have, but the previewContent always return "preview". From API side is ok, and the response.data.content is also correct.

Have no idea what to do next

9
  • @gus27 Semicolons are optional in javascript. Commented Feb 20, 2017 at 17:19
  • read about promises and async calls... Commented Feb 20, 2017 at 17:19
  • ok, i move the previewContent to outside of IF Commented Feb 20, 2017 at 17:24
  • 1
    Have you tried to put the line previewContent = this.response.data.content; in the successCallback function? Commented Feb 20, 2017 at 17:28
  • 1
    Use previewContent = response.data.content; instead of previewContent = this.response.data.content; inside of successCallback. Commented Feb 20, 2017 at 17:30

1 Answer 1

2

The challenge is that you execute an asynchronous function and want to return it's value. In your code example you already returned from the onPreview function while the async function is still executed in the background. In AngularJS you can use promises to solve this kind of problem: "A service that helps you run functions asynchronously, and use their return values (or exceptions) when they are done processing".

BUT: As far I can see from the source the markdown component does not support promises. The onPreview method expects a string to be returned. The only option is to wait inside onPreview until the AJAX request returns - which is strongly discouraged. So IMHO it is not possible to use an AJAX request inside of onPreview.

IF the bootstrap-markdown would support promises you could try this:

app.directive("markdowntextarea", ['$http', '$q', function ($http, $q) { // inject $q
...
onPreview: function (e) {
    console.log('im here!!');
    var deferred = $q.defer();
    if (e.isDirty()) {
        var originalContent = e.getContent();
        $http({
            url: '/api/markdown/',
            data: {"body": originalContent, "code": "a"},
            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 {
        // quando esta vazio
        deferred.resolve("");
    }
    return deferred.promise;
},
...

Here is a JSFiddle that demonstrates the concept. It's an update of Dave Kerr's AngularJS Promises - The Definitive Guide Part 2 - JSFiddle to AngularJS 1.6.

Sign up to request clarification or add additional context in comments.

6 Comments

It still returns "preview"
still it doesn't call my api :/
Hi, it still returns the originalContent. I have no idea why. here: console.log("successCallback", response.data.content); -> I got the right response from api.
d {$$state: Object} 0 Object {status: 0} successCallback from api!!! Some tests I did, it looks like the response from api comes after
@62009030 I updated my answer: According to the source code of bootstrap-markdown I think it is not possible to use an AJAX request inside onPreview.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.