OptimalBPM / angular-schema-form-dynamic-select

AngularStrap and AngularUI dynamic select implementation(static/sync/async/http, filters) for Angular Schema Form
MIT License
55 stars 45 forks source link

Help: Dreamfactory and Schema Form Dynamic Select #35

Closed navjinder closed 9 years ago

navjinder commented 9 years ago

Hi All

I am using dreamfactory for my REST API backend and I am using this code to get the promise back.

controller.js

$scope.thisfunct = function(opt){ var thisval = DreamFactory(db).getList().then(
                    function (data) {
                    return data ;
                          }); 
    return thisval;         
};

and on my form

                {
                    type : "section",
                    htmlClass : "col-xs-2",
                    items : [{
                        key: "integrationId",
                        type: "strapselect",
                         options: {
                                   "map" : {valueProperty: "id", nameProperty: "Platform"} ,  
                                    "asyncCallback":  $scope.thisfunct

                        } 
                    }]
                },

This is the error I am getting

TypeError: Cannot read property 'forEach' of undefined
    at Scope.e.finalizeTitleMap (angular-schema-form-dynamic-select.min.js:1)
    at angular-schema-form-dynamic-select.min.js:1
    at processQueue (angular.js:13292)
    at angular.js:13308
    at Scope.$eval (angular.js:14547)
    at Scope.$digest (angular.js:14363)
    at Scope.$apply (angular.js:14652)
    at done (angular.js:9734)
    at completeRequest (angular.js:9924)
    at XMLHttpRequest.requestLoaded (angular.js:9865)

When I do console.log($scope.thisfunct) I am getting a promise back with the value as the data array. What should I do I have tried every possibility.

nicklasb commented 9 years ago

I am not really sure. The .then should pass a parameter that has a .data property.

nicklasb commented 9 years ago

Wait a minute! I misread your code, if you want to use the asyncCallback, just return the promise:

$scope.thisfunct = function(opt){ 
    return DreamFactory(db).getList();     
};

Your code should work for the normal callback, though.

navjinder commented 9 years ago

Thanks @nicklasb I have tried that too but now the issue is it do not register it as function.

issue-dynamic

nicklasb commented 9 years ago

data seems to be an object with a property, "record". The server should return an array, not an object with a "record" property.

navjinder commented 9 years ago

Oh thanks @nicklasb I will see if I can get the api to spit the array rather than the object. Thanks for looking into.

nicklasb commented 9 years ago

Either that, or you'd have to create some kind of http-promise-fake-proxy with a .then()-function that ASFDS thinks is the actual http promise. It only has to have to put the record on the value.data instead, something like this:

$scope.thisfunct = function(opt) {
    this.then = function(successCallback, failureCallback) {
        this.successCallback = successCallback;
        this.failureCallback = failCallback;
    };

    DreamFactory(db).getList().then(
        function (value) {
            value.data = value.data.record
            this.successCallback(value);
        },
        function (value, status) {
            this.failureCallback(value);
        }
    );
    return this;
};

I don't know if the above works att all, I have no easy way to test it, its just an idea. Either way, promises are a little bit problematic.

I am thinking that perhaps I should add some onAsyncData callback that is called when the promise is fullfilled, enabling users to transform the data anyway they like, I realize that one is not always in control of the back end.

navjinder commented 9 years ago

It worked; so I created a new function and named it getListJson to this file and it works like a charm.

        d.getListJson = function(){
            return $http.get(DSP_URL + '/db/' + table + '/', { isArray: true,
                transformResponse: function(data, headers){
                  var tempdata = JSON.parse(data);
                    return tempdata.record;
            } });
        };

Edit: Thanks @nicklasb

navjinder commented 9 years ago

Regarding your insight Yes, you are right I think it will be great if a user can specify the type of data returned to the async callback. It will be a great option to have. Gladly $http resolves it with transformResponse. Thanks for your time anyways.

nicklasb commented 9 years ago

Interesting, good find, did not know about that one.

In that case, transformResponse is actually sufficient, it is only for the asyncCallbacks that it is neccessary, I'll mention that in the documentation. Good stuff.

nicklasb commented 9 years ago

Added a mention of transformResponse in the docs for the develop branch, closing.