I am using Angular geolocation for get location. Its returning latitude and longitude of location. I want to show map using this latitude and longitude. Also want to show a circle with 5 km. take a look of my code index.html
<html>
<head>
<title>ngGeolocation</title>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.3/angular.js"></script>
<script src="./ngGeolocation.js"></script>
<script src="./index.js"></script>
</head>
<body ng-app="geolocationDemo">
<div ng-controller="AppController">
<h1>Basic (fetch once)</h1>
Latitude: {{location.coords.latitude}}
<br />
Longitude: {{location.coords.longitude}}
<br />
</div>
</body>
</html>
Index.js
angular
.module('geolocationDemo', ['ngGeolocation'])
.controller('AppController', function($scope, $geolocation){
$scope.$geolocation = $geolocation
// basic usage
$geolocation.getCurrentPosition().then(function(location) {
$scope.location = location
});
// regular updates
$geolocation.watchPosition({
timeout: 60000,
maximumAge: 2,
enableHighAccuracy: true
});
$scope.coords = $geolocation.position.coords; // this is regularly updated
$scope.error = $geolocation.position.error; // this becomes truthy, and has 'code' and 'message' if an error occurs
//console.log($scope.coords);
});
ngGeolocation.js
angular
.module('ngGeolocation', [])
.factory('$geolocation', ['$rootScope', '$window', '$q', function($rootScope, $window, $q) {
function supported() {
return 'geolocation' in $window.navigator;
}
var retVal = {
getCurrentPosition: function(options) {
var deferred = $q.defer();
if(supported()) {
$window.navigator.geolocation.getCurrentPosition(
function(position) {
$rootScope.$apply(function() {
retVal.position.coords = position.coords;
deferred.resolve(position);
});
},
function(error) {
$rootScope.$apply(function() {
deferred.reject({error: error});
});
}, options);
} else {
deferred.reject({error: {
code: 2,
message: 'This web browser does not support HTML5 Geolocation'
}});
}
return deferred.promise;
},
watchPosition: function(options) {
if(supported()) {
if(!this.watchId) {
this.watchId = $window.navigator.geolocation.watchPosition(
function(position) {
$rootScope.$apply(function() {
retVal.position.coords = position.coords;
delete retVal.position.error;
$rootScope.$broadcast('$geolocation.position.changed', position);
});
},
function(error) {
$rootScope.$apply(function() {
retVal.position.error = error;
delete retVal.position.coords;
$rootScope.$broadcast('$geolocation.position.error', error);
});
}, options);
}
} else {
retVal.position = {
error: {
code: 2,
message: 'This web browser does not support HTML5 Geolocation'
}
};
}
},
position: {}
//console.log(position);
};
return retVal;
}]);
How to i can do it ? Please suggest me some solutions.
Have a look at angular-google-maps, you should be able to create the map and circle:
http://angular-ui.github.io/angular-google-maps/
I have installed malhar-angular-dashboard module and I want to populate some widgetDefinitions with my rest data.
HTML
<div ng-controller="widgetCtrl">
<div dashboard-layouts="layoutOptions" class="dashboard-container"></div>
</div>
widgetRestService
.factory('widgetRestService',['$http','UrlService','$log','$q',
function($http,UrlService,$log,$q){
var serviceInstance = {};
serviceInstance.getInfo = function(){
var request = $http({method: 'GET', url: '/rest/widgets/getListInfoDashboards'})
.then(function(success){
serviceInstance.widgets = success.data;
$log.debug('serviceInstance.widgets SUCCESS',serviceInstance.widgets);
},function(error){
$log.debug('Error ', error);
$log.debug('serviceInstance.widgets ERROR',serviceInstance.widgets);
});
return request;
};
serviceInstance.getAllWidgets = function () {
if (serviceInstance.widgets) {
return serviceInstance.widgets;
} else {
return [];
}
};
return serviceInstance;
}])
My rest service returns me this array of 3 objects :[{"name":"widgetList","title":" "},{"name":"widgetPie","title":" "},{"name":"widgetTable","title":" "}]
OtherService
.factory("OtherService", ["widgetRestService", "$log", "$q",
function (widgetRestService, $log, $q) {
var deferred = $q.defer();
widgetRestService.getInfo().then(function () {
deferred.resolve(widgetRestService.getAllWidgets());
});
return deferred.promise;
}])
Controller
OtherService.then(function(response){
$scope.layoutOptions = { // layout with explicit save
storageId: 'demo-layouts-explicit-save',
storage: localStorage,
storageHash: 'fs4df4d51',
widgetDefinitions:response , //must be a list
defaultWidgets: [],
explicitSave: true,
defaultLayouts: [
{title: 'Layout 1', active: true, defaultWidgets: []}
]
};
$log.debug('layoutOptions =',$scope.layoutOptions);
});
Result
layoutOptions: Object{defaultLayouts:Array[1],
defaultWidgets:Array[0],
explicitSave:true,
storage:Storage,
storageHash:'fs4df4d51',
storageId: 'demo-layouts-explicit-save',
widgetDefinitions: Array[3]}
TypeError: Cannot read property '$$hashKey' of undefined
at Object.extend (http://localhost:9000/bower_components/angular/angular.js:406:14)
at Object.LayoutStorage (http://localhost:9000/bower_components/malhar-angular-dashboard/dist/malhar-angular-dashboard.js:1064:15)
I searched at line 2: Object.LayoutStorage and I found out this:
angular.extend(defaults, options); //options = undefined (should have some keys and my widgetDefinitions array)
angular.extend(options, defaults);
The options variable is undefined only when I want to setup the $scope.layoutOptions within the then callback function.
Any advice how to set / avoid this ?
The problem is that the dashboard-layouts directive will compile before the asynchronous call from OtherService has finished, which means $scope.layoutOptions will be undefined.
A simple solution is to prevent the dashboard-layouts directive from compiling before $scope.layoutOptions is available.
You can do this by using ng-if:
<div ng-if="layoutOptions" dashboard-layouts="layoutOptions" class="dashboard-container">
</div>
I am trying to display an object (songTitle) from my service. The initial state (tmp) is displayed. If I am changing the object in the service, the view doesnt get updated.
Js:
var party = angular.module("party", []);
party.run(function () {
var tag = document.createElement('script');
tag.src = "http://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
});
party.service('PlayerService', function ($window) {
this.playlist = [
"https://www.youtube.com/watch?v=fnW2uLwHAas",
"https://www.youtube.com/watch?v=iPT8DA32U6U",
"https://www.youtube.com/watch?v=eGjEnfQl37s",
"https://www.youtube.com/watch?v=nFtTY2S20mI",
"https://www.youtube.com/watch?v=UmXQiPLoLTk",
"https://www.youtube.com/watch?v=PbVx85DS9zc",
"https://www.youtube.com/watch?v=ciidn3nEoiE",
"https://www.youtube.com/watch?v=sm0DgkBEnUI",
"https://www.youtube.com/watch?v=J2OCSWF7sAw",
"https://www.youtube.com/watch?v=y_-giRHtuv8",
"https://www.youtube.com/watch?v=iPT8DA32U6U",
"https://www.youtube.com/watch?v=eGjEnfQl37s",
"https://www.youtube.com/watch?v=nFtTY2S20mI",
"https://www.youtube.com/watch?v=UmXQiPLoLTk",
"https://www.youtube.com/watch?v=PbVx85DS9zc"
];
this.player = {};
this.pbTimer = null;
this.songTitle = "tmp";
$window.onYouTubeIframeAPIReady = function () {
this.player = new YT.Player('ytplayer', {
height: '100',
width: '100',
videoId: 'ciidn3nEoiE',
events: {
'onReady': onPlayerReady
}
});
}
function onPlayerReady() {
console.log("db ready");
songTitle = player.getVideoData().title;
console.log(songTitle);
}
this.playVideo = function (url) {
console.log("db playVideo " + url);
player.loadVideoById(url.split("watch\?v=")[1], 0, "large");
console.log(player);
}
});
party.controller("FrontController", function ($scope) {
$scope.front = {};
$scope.front.title = "PARTY";
});
party.controller("PartyController", ['$scope', 'PlayerService', function ($scope, PlayerService) {
$scope.party = {};
$scope.party.title = "PARTY";
Sortable.create(playlist, { /* options */ });
$scope.playlist = PlayerService.playlist;
$scope.playVideo = function (url) {
PlayerService.playVideo(url);
}
$scope.songTitle = PlayerService.songTitle;
}]);
HTML
<body ng-app="party">
<div ng-controller="PartyController" class="container-fluid">
...
<p id="playertitle">{{songTitle}}</p>
...
Log:
db ready
Blackmill Feat. Veela - Life (Full Version)
The problem is in your onPlayerReady function. The line songTitle = player.getVideoData().title; doesn't set songTitle on your service, but rather on the global scope, which is the window object. Simply using this.songTitle won't help either, because this doesn't refer to your service too in the scope of onPlayerReady.
The easiest solution would be to save a reference to your service outside of onPlayerReady and then use it to assign songTitle:
var self = this;
function onPlayerReady() {
console.log("db ready");
self.songTitle = player.getVideoData().title;
console.log(self.songTitle);
}
Still, this is not enough. Because you change songTitle from outside the Angular world (the Youtube player callbacks), you need to call $scope.$apply to notify Angular something has changed.
For that, you need to inject $rootScope into your service:
party.service('PlayerService', function ($window, $rootScope)
and change songTitle using $rootScope.$apply:
var self = this;
function onPlayerReady() {
console.log("db ready");
$rootScope.$apply(function() {
self.songTitle = player.getVideoData().title;
console.log(self.songTitle);
});
}
I'm trying to show two section of my html page with same json data, i don't want to wrap both in same controller as it is positioned in different areas. I have implemented that concept successfully by using local json data in "angular service" see the demo
<div ng-app="testApp">
<div ng-controller="nameCtrl">
Add New
Remove First
<ul id="first" class="navigation">
<li ng-repeat="myname in mynames">{{myname.name}}</li>
</ul>
</div>
<div>
Lot of things in between
</div>
<ul id="second" class="popup" ng-controller="nameCtrl">
<li ng-repeat="myname in mynames">{{myname.name}}</li>
</ul>
JS
var testApp = angular.module('testApp', []);
testApp.service('nameService', function($http) {
var me = this;
me.mynames = [
{
"name": "Funny1"
},
{
"name": "Funny2"
},
{
"name": "Funny3"
},
{
"name": "Funny4"
}
];
//How to do
/*this.getNavTools = function(){
return $http.get('http://localhost/data/name.json').then(function(result) {
me.mynames = result.mynames;
return result.data;
});
};*/
this.addName = function() {
me.mynames.push({
"name": "New Name"
});
};
this.removeName = function() {
me.mynames.pop();
};
});
testApp.controller('nameCtrl', function ($scope, nameService) {
$scope.mynames = nameService.mynames;
$scope.$watch(
function(){ return nameService },
function(newVal) {
$scope.mynames = newVal.mynames;
}
)
$scope.addName = function() {
nameService.addName();
}
$scope.removeName = function() {
nameService.removeName();
}
});
jsfiddle
Next thing i want to do is to make a http request to json file and load my two section with data, and if i add or remove it should reflect in both areas.
Any pointers or exisisitng demo will be much helpful.
Thanks
The reason why only one ngRepeat is updating is because they are bound to two different arrays.
How could it happen? It's because that you have called getNavTools() twice, and in each call, you have replaced mynames with a new array! Eventually, the addName() and removeName() are working on the last assigned array of mynames, so you're seeing the problem.
I have the fix for you:
testApp.service('nameService', function($http) {
var me = this;
me.mynames = []; // me.mynames should not be replaced by new result
this.getNavTools = function(){
return $http.post('/echo/json/', { data: data }).then(function(result) {
var myname_json = JSON.parse(result.config.data.data.json);
angular.copy(myname_json, me.mynames); // update mynames, not replace it
return me.mynames;
});
};
this.addName = function() {
me.mynames.push({
"name": "New Name"
});
};
this.removeName = function() {
me.mynames.pop();
};
});
testApp.controller('nameCtrl', function ($scope, nameService) {
// $scope.mynames = nameService.mynames; // remove, not needed
nameService.getNavTools().then(function() {
$scope.mynames = nameService.mynames;
});
/* Remove, not needed
$scope.$watch(
function(){ return nameService },
function(newVal) {
$scope.mynames = newVal.mynames;
}
);
*/
$scope.addName = function() {
nameService.addName();
};
$scope.removeName = function() {
nameService.removeName();
};
});
http://jsfiddle.net/z6fEf/9/
What you can do is to put the data in a parent scope (maybe in $rootScope) it will trigger the both views ,And you don't need to $watch here..
$rootScope.mynames = nameService.mynames;
See the jsFiddle
I am using John Papa's Angular HotTowel and I don't know how to incorporate Angulars ng-grid into the html. Here is what I've added thanks to wonderful help from stondo. Breeze seems to be adding extra information that is no allowing ng-grid to render the data in the grid. Is there a way to strip the extra info that breeze sends or a work around for ng-grid to behave correctly with breeze data?
angular.module('app').controller(controllerId,
['common', 'datacontext','$scope', '$http', grid2]);
function grid2(common, datacontext, $scope, $http) {
.....
.....
} else {
$http.get('/breeze/Breeze/NoBadgePersonnels').success(function (largeLoad) {
$scope.setPagingData(largeLoad, page, pageSize);
});
activate();
function activate() {
common.activateController([mockData()], controllerId)
.then(function() { log('Activated Grid View'); });
function mockData() {
return datacontext.getEmployeePartialsNoBadges().then(function (data) {
return vm.grid2 = data.results;
});
}
}
Additional information
Datacontext.js looks as follows:
(function () {
'use strict';
var serviceId = 'datacontext';
angular.module('app').factory(serviceId,
['common', 'config', 'entityManagerFactory', datacontext]);
function datacontext(common, config, emFactory ) {
var EntityQuery = breeze.EntityQuery;
var getLogFn = common.logger.getLogFn;
var log = getLogFn(serviceId);
var logError = getLogFn(serviceId, 'error');
var logSuccess = getLogFn(serviceId, 'success');
var manager = emFactory.newManager();
var $q = common.$q;
var service = {
getPeople: getPeople,
getMessageCount: getMessageCount,
getEmployeePartials: getEmployeePartials,
getEmployeePartialsNoBadges: getEmployeePartialsNoBadges
};
var entityNames = {
personnel: 'Personnel'
};
return service;
function getEmployeePartialsNoBadges() {
var orderBy = 'lname';
var employees; //variable to hold employees once we get them back
//use query using Employees resource
return EntityQuery.from('NoBadgePersonnels')
.select('id, fname, lname, class, zip, cntySnrDte')
.orderBy(orderBy)
.toType('Personnel')
.using(manager).execute()
.then(querySucceeded, _queryFailed)
function querySucceeded(data) {
employees = data.results;
log('Retrieved [Employee Partials] from remote data source', employees.length, true);
//log('Retrieved [Employee Partials] from remote data source');
return employees;
}
}
function _queryFailed(error) {
var msg = config.appErrorPrefix + 'Error retrieving data from entityquery' + error.message;
logError(msg, error);
throw error;
}
=================================
It seems like the grid sees 5 items that I queried for, however the items don't want to display on the cells. Red arrow indicates that it allocated 5 rows, and green arrow indicates that I have selected one of the rows. Still doesn't display the records.
thanks
nick
I had to modify John Papa's Hottowel.Angular template, because it wasn't working as expected with latest angular/breeze versions. I'll later share a github link and a blog post about that.
I was able to get ng-grid working just adding $scope and $http to the controller. Read the comment inside the code block to see how it could be entirely done without inject $http.
(function () {
'use strict';
var controllerId = 'corrieri';
angular.module('app').controller(controllerId, ['common', 'datacontext', '$scope', '$http', corrieri]); //'$http', '$scope',
function corrieri(common, datacontext, $scope, $http) { //,$http, $scope
var getLogFn = common.logger.getLogFn;
var log = getLogFn(controllerId);
var vm = this;
$scope.corrieriList = [];
vm.corrieri = [];
vm.news = {
title: 'Corrieri',
description: 'Lista Corrieri'
};
vm.title = 'Corrieri';
//ng-grid test
$scope.filterOptions = {
filterText: "",
useExternalFilter: false
};
$scope.totalServerItems = 0;
$scope.pagingOptions = {
pageSizes: [10, 20, 30],
pageSize: 10,
currentPage: 1
};
$scope.setPagingData = function (data, page, pageSize) {
data = data.map(function (item) {
return {
PK_ID: item.PK_ID,
Ragione_Sociale: item.Ragione_Sociale,
Telefono: item.Telefono,
Nazionalita: item.Nazionalita,
Indirizzo: item.Indirizzo,
Cap: item.Cap,
Provincia: item.Provincia,
Descrizione: item.Descrizione
};
});
var pagedData = data.slice((page - 1) * pageSize, page * pageSize);
$scope.corrieriList = pagedData; //.results;
$scope.totalServerItems = data.length;
if (!$scope.$$phase) {
$scope.$apply();
}
};
$scope.getPagedDataAsync = function (pageSize, page, searchText) {
setTimeout(function () {
var data;
if (searchText) {
var ft = searchText.toLowerCase();
$http.get('breeze/Corrieri/GetCorrieri').success(function (largeLoad) {
var myModArray = largeLoad.map(function (item) {
return {
Pk_ID: item.Pk_ID,
Ragione_Sociale: item.Ragione_Sociale,
Telefono: item.Telefono,
Nazionalita: item.Nazionalita,
Indirizzo: item.Indirizzo,
Cap: item.Cap,
Provincia: item.Provincia,
Descrizione: item.Descrizione
};
});
data = myModArray.filter(function (item) {
return JSON.stringify(item).toLowerCase().indexOf(ft) != -1;
});
$scope.setPagingData(data, page, pageSize);
});
} else {
$http.get('breeze/Corrieri/GetCorrieri').success(function (largeLoad) {
$scope.setPagingData(largeLoad, page, pageSize);
});
}
}, 100);
};
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage);
$scope.$watch('pagingOptions', function (newVal, oldVal) {
if (newVal !== oldVal && newVal.currentPage !== oldVal.currentPage) {
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText);
}
}, true);
$scope.$watch('filterOptions', function (newVal, oldVal) {
if (newVal !== oldVal) {
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText);
}
}, true);
$scope.gridOptions = {
data: 'corrieriList',
enablePaging: true,
showFooter: true,
showFilter: true,
enableCellEdit: true,
enableColumnResize: true,
enableColumnReordering: true,
pinSelectionCheckbox: true,
totalServerItems: 'totalServerItems',
pagingOptions: $scope.pagingOptions,
filterOptions: $scope.filterOptions
};
//ng-grid test end
activate();
function activate() {
var promises = [getCorrieri()];
common.activateController(promises, controllerId)
.then(function () {
log('Activated Corrieri View');
});
}
//This function was used to get data using Breeze Controller
//and I was even able to use it to bind data to ng-grid
//calling the function getCorrieri inside my controller and binding
//gridOptions data to vm.corrieri or just the name of the function (in my case getCorrieri)
// $scope.gridOptions = { data: getCorrieri}
//Be aware that since we r using a Breeze Controller data retrieved have additional
//informations, so we have to remove those, if we bind using vm.corrieri.
//I found it easier to implement paging using $http and $scope, even though I think
//I could do it using only $scope and breeze.
//getCorrieri().then(function() {
// angular.forEach(vm.corrieri, function (cor) {
// delete cor._backingStore['$id'];
// delete cor._backingStore['$type'];
// $scope.corrieriList.push(cor._backingStore);
// });
//});
function getCorrieri() {
return datacontext.getCorrieri().then(function (data) {
return vm.corrieri = data.results;
});
}
}
})();
Below you can find my html for reference. Make sure to surround your's ng-grid div with data-ng-controller or just ng-controller='corrieri'
<section id="corrieri-view" class="mainbar" data-ng-controller="corrieri as vm">
<section class="matter">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="widget wgreen">
<div data-cc-widget-header title="Corrieri" allow-collapse="true"></div>
<div class="widget-content text-center text-info">
<div data-ng-controller='corrieri'>
<div class="gridStyle col-md-12" ng-grid="gridOptions">
</div>
</div>
<div class="widget-foot">
<div class="clearfix"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</section>
Btw, don't forget to add 'ngGrid' to your modules list in app.js
var app = angular.module('app', ['ngGrid', other modules])
and also include ng-grid css and js in index.html (that is obvious, but better safe than sorry)
I struggled a few days to get this working properly, so I hope to help anyone out there having the same problem.
Try this out:
angular.module('app').controller(controllerId, ['common', 'datacontext', '$scope', grid]);
function grid(common, datacontext, $scope) {
$scope.gridOptions = {
data: 'vm.employees'
};
activate();
function activate() {
common.activateController([getEmployees()], controllerId)
.then(function () { log('Activated Grid View'); });
}
//get data for employees
function getEmployees() {
return datacontext.getEmployeePartialsNoBadges().then(function (mydata) {
return vm.employees = data;
});
}
}
here is an image of what I see
and here is the code I changed:
function getEmployees() {
return datacontext.getEmployeePartialsNoBadges().then(function (mydata) {
log(JSON.stringify(mydata));
return vm.employees = mydata.data;
});
Here is some additional info showing the data is coming through. Remote data source shows 1496 records. The preview for /breeze/breeze show data. I've blanked out sensitive info.
Here is the getEmployeePartialsNoBadges() method in my datacontext that was using entity framework:
function getEmployeePartialsNoBadges() {
var orderBy = 'lname';
var employees; //variable to hold employees once we get them back
//use query using Employees resource
return EntityQuery.from('NoBadgePersonnels')
.select('id, fname, lname, class, zip, cntySnrDte')
.orderBy(orderBy)
.toType('Personnel')
.using(manager).execute()
.then(querySucceeded, _queryFailed)
function querySucceeded(data) {
employees = data.results; //fillup the variable for employee with results
log('Retrieved [Employee Partials] from remote data source', employees.length, true);
//log('Retrieved [Employee Partials] from remote data source');
return employees;
}
}
============================== Nick ==============================
This is what my new mockup looks like now and I put this in datacontext calling it getPeople:
function getPeople() {
var people = [
{ firstName: 'John', lastName: 'Papa', age: 25, location: 'Florida' },
{ firstName: 'Ward', lastName: 'Bell', age: 31, location: 'California' },
{ firstName: 'Colleen', lastName: 'Jones', age: 21, location: 'New York' },
{ firstName: 'Madelyn', lastName: 'Green', age: 18, location: 'North Dakota' },
{ firstName: 'Ella', lastName: 'Jobs', age: 18, location: 'South Dakota' },
{ firstName: 'Landon', lastName: 'Gates', age: 11, location: 'South Carolina' },
{ firstName: 'Haley', lastName: 'Guthrie', age: 35, location: 'Wyoming' }
];
return $q.when(people);
}
I have reworked html and controller code to clean things up. The html is now call grid2.html and the controller is called grid2.js
(function () {
'use strict';
var controllerId = 'grid2';
angular.module('app').controller(controllerId,
['common', 'datacontext','$scope', grid2]);
function grid2(common, datacontext, $scope) {
var vm = this;
vm.grid2 = [];
$scope.gridOptions = {
data: 'vm.grid2'
};
var getLogFn = common.logger.getLogFn;
var log = getLogFn(controllerId);
vm.activate = activate;
vm.title = 'Grid2';
activate();
function activate() {
common.activateController([mockData()], controllerId)
.then(function() { log('Activated Grid View'); });
function mockData() {
return datacontext.getPeople().then(function (mydata) {
log(JSON.stringify(mydata));
return vm.grid2 = mydata.data;
});
}
}
}
})();
controller grid2.js
<section class="mainbar" data-ng-controller="grid2 as vm">
<section class="matter">
<div class="container">
<div class="row">
<div class="widget wgreen">
<div data-cc-widget-header title="Grid 2"></div>
<div class="widget-content user">
</div>
this is grid2 test
<div class="gridStyle" ng-grid="gridOptions"></div>
<div class="widget-foot">
<div class="clearfix"></div>
</div>
</div>
</div>
</div>
</section>
Here what the screen looks like now. still no data in the grid:
In the debug, the data property shows undefined still
The mydata does contain array of data
The vm is an empty array on the return statement
The vm.grid becomes empty after the return and I'm unsure what the vm is also
The console show data being present