I want to display feature properties that have been selected in an OpenLayers3 map. I am using AngularJS and try to update the currently selected feature properties using `$scope$watch`.

I have a MapManager file that is used to handle all necessary OL3 operations:

    // DEFAULT variables
    var defaultCenter = [-2.15, 52.267];
    var defaultZoom = 12;
    var epsgWGS84 = 'EPSG:4326';
    var epsgDefaultMapOL = 'EPSG:3857';
    var defaultTarget = 'map';
    
    // Constructor
    function MapManager(target, center, zoom){
    	// check if parameters are set - use defaults otherwise
    	if(!target){
    		target = defaultTarget;
    	}
    	if(!center){
    		center = defaultCenter;
    	}
    	if(!zoom){
    		zoom = defaultZoom;
    	}
    	this.map = this.initMap(target, center, zoom);
    	this.selectedFeatureProperties = {prop1: "initialValue"};
    }
    
    
    // Getter for feature properties
    MapManager.prototype.getSelectedFeatureProperties = function(){
        return this.selectedFeatureProperties;
    };
    
    // Setter for feature properties
    MapManager.prototype.setSelectedFeatureProperties = function(feature){
    	var this_ = this;
    	console.log("setting selected feature properties...");
    	var displayProperties = {};
    	if(feature != null){
    		$.each(feature.getProperties(), function(key, value) {
    			// skip the geometry property
    			if(key != "geometry"){
    				displayProperties[key] = value;
    			}
    		});
    	}
    	console.log(displayProperties);
    	this.selectedFeatureProperties = displayProperties;
    }
    
    // some geojson with lines
    var geojsonObject = {
        'type': 'FeatureCollection',
        'crs': {
            'type': 'name',
            'properties': {
                'name': 'EPSG:4326'
            }
        },
        'features': [
            {
                'type': 'Feature',
                'properties': {
                	'prop1': 'feature1',
    				'prop2': 'Blub'
                },
                'geometry': {
                    'type': 'LineString',
                    'coordinates': [
                        [-2.176, 52.266], [-2.166, 52.276]
                    ]
                }
            },
            {
                'type': 'Feature',
                'properties': {
                	'prop1': 'feature2',
    				'prop2': 'Test'
                },
                'geometry': {
                    'type': 'LineString',
                    'coordinates': [
                        [-2.132, 52.272], [-2.145, 52.258]
                    ]
                }
            }
        ]
    };
    
    // create vector source with geojson
    var vectorSource = new ol.source.Vector({
    	features: (new ol.format.GeoJSON()).readFeatures(geojsonObject, {
    		dataProjection: 'EPSG:4326',
    		featureProjection: 'EPSG:3857'
    	})
    });
    
    
    // ### Create layers
    // create osm layer
    function createLayerWebOSM(){
    	return new ol.layer.Tile({
            source: new ol.source.OSM(),
    		projection: epsgDefaultMapOL
    	});
    }
    
    // create vector layer (using geojson vector source)
    var vectorLayer = new ol.layer.Vector({
    	source: vectorSource
    });
    
    
    // Initialize map
    MapManager.prototype.initMap = function(target, center, zoom){
    	var this_ = this;
    	var map = new ol.Map({
    		target: target,
    		layers: [createLayerWebOSM(), vectorLayer],
    		view: new ol.View({
    		center: ol.proj.transform(center, epsgWGS84, epsgDefaultMapOL),
    		zoom: zoom
    	  })
    	});
    	
    	// make vector layer selectable
    	vectorLayer.set('selectable', true);
    	
    	map.addInteraction(new ol.interaction.Select({
    		layers: function(layer) {
    			return layer.get("selectable") == true;
    		}
    	}));
    	
    	
    	// add click interaction
    	map.on("click", function(e) {
    		map.forEachFeatureAtPixel(e.pixel, function (feature, layer) {
    			console.log("new feature selected -> ");
    			console.log(feature);
    			this_.setSelectedFeatureProperties(feature);
    			console.log("new feature properties -> ");
    			console.log(this_.getSelectedFeatureProperties());
    		});
    	});
    	return map;
    }

When a feature is clicked on the map it is stored and can be accessed with an according getter which is watched in the Angular controller:

    var app = angular.module('myApp', []);
    
    // Controller
    app.controller('appController', function($scope, $q){
    	$scope.mapManager = new MapManager();
    	$scope.selectedFeatureProperties = {};
    	
    	// watch if the selected feature changes
    	$scope.$watch(function() {
    		return $scope.mapManager.getSelectedFeatureProperties();
            //return $scope.mapManager.getSelectedFeature();
    	},
    	function(newFeature, oldFeature) {
    		console.log("change detected...");
    		$scope.selectedFeatureProperties = $scope.mapManager.getSelectedFeatureProperties();
    	}, true);
    	
    });



I want to display the properties of the currently selected feature in a table:


    <div id="main" data-ng-controller="appController">
    	<!-- table with selected feature inforamtion -->
    	<h4> Selected Feature Properties </h4>
    	<table>
    		<tr>
    			<th> Property </th>
    			<th> Value </th>
    		</tr>
    		<tr ng-repeat="(property, value) in selectedFeatureProperties">
    			<td>{{ property }}</td>
    			<td>{{ value }}</td>
    		</tr>
        </table>
    		
    	<div id='map'></div>
    </div>

It seems that the change is ignored.

You can see the essential part of the code at this [JSFiddle][1]. Some logs indicate that the selectedFeature variable is actually changing...

What am I doing wrong? Is there an easier way to do this (instead of using `$scope$watch`)?

**EDIT:** In the MapManager I am now saving the feature properties (`selectedFeatureProperties`) directly and not the ol.Feature itself. I tried `$watch` and `$watchCollection` with and without true/false as last parameter but the listener is not called when the selectedFeatureProperties are changing... If I am understanding the third parameter correctly in my case it should not matter if it is true or false because the reference of the selectedFeatureProperties and the values of the properties are both changing?
Moreover I tried to pass the watchExpression as String

    "mapManager.getSelectedFeatureProperties()"

or as a function

    function(){
      return $scope.mapManager.getSelectedFeatureProperties();
    },

but that did not change anything. I adjusted the [JSFiddle][2] with some comments so you can see what I tried...


  [1]: https://jsfiddle.net/umsv1860/28/
  [2]: https://jsfiddle.net/umsv1860/28/