0

I have this code in my service

orderSewaService.vehicleDetail = function (license_plate) {

        //var defer = $q.defer();

        var config = {
            headers: {
                'X-Parse-Application-Id': parseAppId
            },
            params: {
                where: {
                    vehicle_license_plate: license_plate,
                    vehicle_status: 'available'
                },
                limit: 1,
                include: 'car_id.car_class_id,pool_id.city_id,partner_id.user_id'   
            }

        }

        return $http.get('http://128.199.249.233:1337/parse/classes/vehicle', config).then(function (response) {
            var detail = {
                license_plate: response.data.results[0].vehicle_license_plate,
                photo: response.data.results[0].vehicle_photo,
                partner_name: response.data.results[0].partner_id.user_id.full_name,
                year: response.data.results[0].vehicle_year,
                class: response.data.results[0].car_id.car_class_id.name,
                pool_address: response.data.results[0].pool_id.pool_address,
                city: response.data.results[0].pool_id.city_id.city_name,
                zone_id: response.data.results[0].zone_id.objectId,
                car_class_id: response.data.results[0].car_id.car_class_id.objectId         
            };

            return detail;

            //defer.resolve(detail);
        }, function (error) {
            //defer.reject(error);
            return error;
        });             

        //return defer.promise;     

    };

in my controller

$scope.vehicle = {};
 orderSewaService.vehicleDetail($routeParams.license_plate).then(function(response){
                $scope.vehicle = response;//rendered in view
                console.log($scope.vehicle); //log object success
            }, function (error) {
                console.log(error);
            });

            console.log($scope.vehicle); //doesn't work //empty object
            //My goal is I will call other service function like this
            orderSewaService.infoTarif($scope.vehicle.zone_id, $scope.vehicle.car_class_id).then(...);

Already read this access scope data from outside function but looks like to complex or not suit for my simple goal.

How I can access $scope.vehicle outside function or how to achieve my goal ?

And I don't think $rootScope is good solution in this case.

1
  • 1
    when you are taking about outside function do you mean outside the http's response call back function, or the function in the controller? They are two different things. Commented Nov 24, 2016 at 2:40

3 Answers 3

2

You need to declare $scope.vehicle outside the function call,

somewhere in your controller at the begining,

If it's an array

$scope.vehicle =[];
Sign up to request clarification or add additional context in comments.

2 Comments

doesn't work updated my question with your code suggested
problem is , it is getting printed before getting the result. since its an asynchronous call you need to put the inside a callback
0

The problem is with the way this controller code flow works.

$scope.vehicle = {}; //vehicle property is declared and defined as empty obj in the $scope

orderSewaService.vehicleDetail($routeParams.license_plate) This is an ajax call, js calls this method and then goes to the next line , after the end of this method, i.e. console.log($scope.vehicle); without waiting for the call to return and populate $scope.vehicle with your response.


So, try this:

In Controller:

`

$scope.vehicle = {};
orderSewaService.vehicleDetail($routeParams.license_plate).then(function(response){
                $scope.vehicle = response;//rendered in view
                getInfoTarif();
            }, function (error) {
                console.log(error);
            });
function getInfoTarif(){
console.log($scope.vehicle);
orderSewaService.infoTarif($scope.vehicle.zone_id,$scope.vehicle.car_class_id).then(...);
}

`

Comments

0

I think there are two matter of concerns in this question.

Firstly - sync & async methods

Since orderSewaService.vehicleDetail is asynchronous, $scope.vehicle would be null.

If you are not sure what that means, compare the two:

var foo = null;

foo = ['a','b'];

console.log(foo); // ['a','b']

versus

var foo = null;

setTimeout(function(){
    foo = ['a','b'];
    console.log(foo); // array
}, 500); // or any value including zero

console.log(foo); // null

Conclusively, your code should look like this:

$scope.vehicle = {};
orderSewaService
    .vehicleDetail($routeParams.license_plate)
    .then(function(response){
        $scope.vehicle = response;//rendered in view
        console.log($scope.vehicle); //log object success

        //My goal is I will call other service function like this
        orderSewaService.infoTarif($scope.vehicle.zone_id, $scope.vehicle.car_class_id).then(...);

    }, function (error) {
        console.log(error);
    });

There are a ton of articles and docs that describe this, if you are further interested.

Secondly - load contents before reaching controller

Now, from how you described the problem, it seems like you also want to load the contents of orderSewaService.vehicleDetail based on a URL parameter before it reaches the controller. Otherwise, you will have to call orderSewaService.vehicleDetail and orderSewaService.infoTarif in every controller.

A much cleaner and more common approach is to use ui-router's $stateProvider. Tutorials here

If you run a few examples from their docs, you can inject dependencies into your controller like this:

app.route.js

$stateProvider
.state('vehicles', {
    url: '/vehicles',
    resolve: { 
        vehicles: ['VehiclesService', function(VehiclesService){
            return VehiclesService.getAll();
        }]
    },
    controller: 'VehiclesListCtrl',
    templateUrl: 'vehicles.html'
})
.state('vehicles.detail', {
    url: '/vehicles/:vehicleId',
    resolve: { 
        info: ['VehiclesService', '$stateParams', function(VehiclesService, $stateParams){
            return VehiclesService.get($stateParams.vehicleId)
                 .then(function(vehicle){
                     return orderSewaService.infoTarif(vehicle.zone_id, vehicle.car_class_id)
                     .then(function(tarif){
                         return {
                             vehicle: vehicle,
                             tarif: tarif
                         };
                     });
                 });
        }]
    },
    controller: 'VehicleDetailCtrl',
    templateUrl: 'vehicle.detail.html'
});

vehicle.detail.controller.js

.controller('VehicleDetailCtrl', VehicleDetailCtrl);

    VehicleDetailCtrl.$inject = [
        '$scope',
        'info'
    ];

    function VehicleDetailCtrl(
        $scope,
        info
    ) {
        console.log('vehicle %o tarif %o', info.vehicle, info.tarif);
    }

vehicles.controller.js

.controller('VehiclesCtrl', VehiclesCtrl);

    VehiclesCtrl.$inject = [
        '$scope',
        'vehicles'
    ];

    function VehiclesCtrl(
        $scope,
        vehicles
    ) {
        console.log('vehicles list %o', vehicles);
    }

To access this state, you need to do something like

menu.html

<a ui-sref="vehicles.detail({vehicleId: 1234})">

I purposely did not make vehicles route abstract for illustration purposes. You may want to look into that if you want to create nested state/views. I hope this helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.