Polymer 1.x Data Binding Remote Values - polymer-1.0

This is the custom tag that I have in the HTML, I want {{value}} to change depending on the latency when the element loads.
<my-latency value={{value}}></my-state>
Below is the custom element I'm trying to write which does calculate the latency between the user and the server. But I dont know how to get the value of latency (which console.log's out perfectly) back to the value of the custom tag.
<link rel="import" href="../../bower_components/polymer/polymer.html">
<script>
Polymer({
is: "my-latency",
ready: function() {
socket = io('http://198.191.94.231:9000');
socket.emit('latency', Date.now(), function(startTime) {
var latency = Date.now() - startTime;
console.log(latency); // returns: 203
});
},
This is where it all starts to go wrong...
properties: {
latency: number,
response: {
value: latency,
type: number,
reflectToAttribute: true,
readOnly: true,
notify: true
}
},
responseHandler: function(response) {
this.value = latency;
}
});
</script>

Looks like ready() is missing the assignment to this.value
var latency = Date.now() - startTime;
this.value = latency;

Related

AngularJS wait until element is fully loaded

I am currently working on a pdftron implementation and it looks like the webviewer is not loaded fast enough at the point when webviwer tries to load the document. How would you set some kind of ready element so it waits until the webViewer is ready to load a document?.
viewer = new PDFTron.WebViewer({
path: 'WebViewer',
type: 'html5',
documentType: 'pdf'
}, element);
$scope.watch('url', function(blobVal) {
viewer.loadDocument(blobVal);
}
I am getting an undefined on viewer.loadDocument and its because viewer is not fully loaded. It happens intermittently.
You want to wait for the WebViever ready event. Please see the guide below:
https://www.pdftron.com/documentation/web/guides/fundamentals/webviewer#details-of-instantiation
var myWebViewer = new PDFTron.WebViewer({
initialDoc: 'mydoc.pdf',
ui: 'legacy'
}, viewerElement);
viewerElement.addEventListener('ready', function() {
// API functions are now ready to be called on myWebViewer
});
Please also see the following link:
https://www.pdftron.com/api/web/PDFTron.WebViewer.html#event:ready__anchor
I believe the following code makes more sense
$scope.viewer = new PDFTron.WebViewer({
path: 'WebViewer',
type: 'html5',
documentType: 'pdf'
}, element);
$scope.$watch('viewer', function(newVal, oldVal) {
if (newVal instanceof Blob && newWal !== oldVal) {
viewer.loadDocument(newVal);
}
}
You can use javascript timeout.
setTimeout(function(){
// You can write functions that will load after Angular elements.
},500);

AngularJS Include Refresh

I have a html page which I am including as follows.
<ng-include src="lowerTabURL"></ng-include>
This page contains a devextreme control which loads a datasource via ajax.
html:
<div class="tab-container" style="height:100%; width:100%">
<div dx-tabs="lowerTabOptions" dx-item-alias="lowerTab">
</div>
</div>
controller:
DemoApp.controller('NavigationController', function DemoController($scope, $templateCache) {
$scope.lowerTabURL = "LowerPanelTest";
$scope.currentSidebarId = 10100;
$scope.lowerTabOptions = {
dataSource: new DevExpress.data.CustomStore({
load: function (loadTabOptions) {
console.log('get tabs');
var d = $.Deferred();
$.ajax({
url: 'GetLowerTabs',
data: { currentSidebarId: $scope.currentSidebarId },
type: 'GET',
success: function (result) { console.log(result); d.resolve(result); }
});
return d.promise();
}
}),
animationEnabled: true,
swipeEnabled: true,
itemTitleTemplate: 'title',
height: '100%'
};
$scope.navBarClicked = function (sidebarId) {
console.log(sidebarId);
$scope.currentSidebarId = sidebarId;
}
});
This works correctly however I have a navbar which when clicked, should change the tab control.
Currently I am changing the sidebarId which gets passed to the ajax call but I need a way to reload the include page so that this is called again. I have tried changing the lowerTabUrl and then changing it back again but this doesnt refresh the page. What is the best way to do this?
It depends on your angular version, you will need to watch after changes of value for param sidebarId, # angular 1 this is achieved by scope.watch
scope.$watch('sidebarId', function(newValue, oldValue) {
// ..call refresh here
});
at angular 1.5 and later you can override ngOnChages
this.$onChanges = function (changesObj) {
if (changesObj.sidebarId) {
// changesObj.sidebarId.currentValue
}
};

Angular Leaflet Directive Not updating marker position

I'm trying to use angular-leaflet-directive with Websocket, though I'm able to integrate successfully, the positions of the markers are not getting updated dynamically. However The positions of map gets updated if I move mouse over the map but doesn't get updated when the lat-lng value changes.
Below is code snippet of module.
$scope.markers = {};
angular.extend($scope, {
bounds : $scope.bounds,
center : {},
kppaths : {},
events: {
markers:{
enable: [ 'move' ]
}
}
});
$stomp.setDebug(function(args) {
$log.info(args);
});
$scope.startWS = function() {
var connectionHeaders = {};
// Connect
$stomp.connect("/kp-ws").then(function(frame){
$log.info("connected to server")
$stomp.send('/app/start', {});
// Subscribe for message
$scope.subscription = $stomp.subscribe('/topic/kp', function(
data, headers, res) {
angular.forEach(data, function(k,v){
$scope.markers[k.markerId].lat = k.lat;
$scope.markers[k.markerId].lng = k.lng;
});
});
});
};
$scope.stopWS = function() {
$stomp.send('/app/stop', {});
$scope.subscription.unsubscribe();
$stomp.disconnect();
};
$scope.$on("leafletDirectiveMarker.move", function(event, args){
$log.info(args.model.lat);
});
} ]);
The html file
<div class="card-block">
<leaflet bounds="bounds" geojson="geojson" lf-center="center"
paths="kppaths" markers="markers" event-broadcast="events" width="100%" height="480px"></leaflet>
</div>
Is I'm missing something, Please let me know or suggest how to fix this issue?
The possible workaround I found is:
leafletData.getMap().then(function (map) {
$timeout(function() {map.invalidateSize()});
});
basically, once the map is invalidated, it updates markers' position. Although not perfect, considering some performance issues, the workaround at least solves the main issue.

Any angular example for knob-style Rotary Switch?

Hi i'm looking for an Angular.js example like this,
http://www.jqueryscript.net/form/Knob-Style-Rotary-Switch-Plugin-with-jQuery-rotarySwitch.html
Ideally a complete path from rotary switch to posting some commands to the service side, based in the switch position.
Any good example please ?
Otherwise i plan to write a angular module using this sample jquery file, every time the rotary switch moves to a new location, it's call $http.post to let service side know. The main module will use this rotary switch module. But really don't want to write my own.
Like mentioned in the comments I also think that there is probably no directive for that rotary switch plugin.
So something like in the demo below should work for this. I've just created a directive where I've initialized the jquery plugin inside the link method (dom is ready to manipulate inside postLink).
To reduce http traffic I've added a timeout so that the callback is called at a lower rate. (see rotKnob_delayedCallback in DEFAULT_OPTS)
You could write a directive for every jQuery plugin where you can't find a wrapper directive.
Please also have a look at the browser console. In jsfiddle you can see the post echo of the position in the console.
Here is also the fiddle to the demo below.
angular.module('demoApp', ['rotaryKnobModule'])
.factory('knobService', KnobService)
.controller('mainController', MainController)
angular.module('rotaryKnobModule', [])
.constant('DEFAULT_OPTS', {
// Minimal value
minimum: 0,
// Maximum value
maximum: 12,
// Step size
step: 1,
// Snap to steps in motion
snapInMotion: true,
// Start point in deg
beginDeg: 0,
// Length in deg
lengthDeg: 360,
// // Which value will used, if the the start and the end point at the same deg.
minimumOverMaximum: true,
// Show input element
showInput: false,
// Show deg marks
showMarks: false,
// Theme class
themeClass: 'defaultTheme',
// custom option for directive
rotKnb_delayedCallback: 500 // in ms
})
.directive('rotaryKnob', RotaryKnob);
function MainController(knobService, $timeout) {
var vm = this;
vm.position = 0;
vm.options = {
minimum: 0,
maximum: 100
};
vm.onChange = function(pos) {
console.log('current position change handler', pos);
knobService.postPos(pos).then(function(response){
console.log('success', response)
}, function(response) {
console.log('failed');
});
}
}
function KnobService($http) {
return {
postPos: function(pos) {
var data = $.param({
json: JSON.stringify({
position: pos
})
});
return $http.post('/echo/json/', data);
}
}
}
function RotaryKnob($timeout) {
return {
scope: {},
bindToController: {
pos: '=',
options: '=?',
onChange: '&?'
},
controllerAs: 'rotKnobCtrl',
template: '<input type="text" class="rotarySwitch"/>',
link: function(scope, element, attrs) {
var options = scope.rotKnobCtrl.options,
ctrl = scope.rotKnobCtrl,
pos = 0, changeTimeout;
//console.log(options);
var $rotKnob = $(element).rotaryswitch(options);
$rotKnob.on('change', function() {
pos = parseInt($(this).val());
scope.rotKnobCtrl.pos = pos;
if ( !changeTimeout ) // reduce update rate to server
changeTimeout = $timeout(function() {
ctrl.onChange({pos: pos});
changeTimeout = null;
}, options.rotKnb_delayedCallback);
scope.$apply();
})
},
controller: function(DEFAULT_OPTS) {
var self = this;
self.pos = 0;
//console.log(self.options);
self.options = angular.extend({}, DEFAULT_OPTS, self.options);
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdn.rawgit.com/r12r/com.redwhitesilver.rotarySwitch/master/jquery.rotaryswitch.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.4/angular.js"></script>
<script src="https://cdn.rawgit.com/r12r/com.redwhitesilver.rotarySwitch/master/jquery.rotaryswitch.js"></script>
<div ng-app="demoApp" ng-controller="mainController as mainCtrl">
<rotary-knob
pos="mainCtrl.position"
options="mainCtrl.options"
on-change="mainCtrl.onChange(pos)"
></rotary-knob>
Current position {{mainCtrl.position}}
</div>

Return a formatted array of events

I'm trying to integrate Angular Bootstrap Calendar to my Laravel 5 project. Right now, the calendar works using the provided pre-populated demo list of events.
vm.events = [
{
title: 'An event',
type: 'warning',
startsAt: moment().startOf('week').subtract(2, 'days').add(8, 'hours').toDate(),
endsAt: moment().startOf('week').add(1, 'week').add(9, 'hours').toDate(),
draggable: true,
resizable: true
}, {
title: 'Event 2',
type: 'info',
startsAt: moment().subtract(1, 'day').toDate(),
endsAt: moment().add(5, 'days').toDate(),
draggable: true,
resizable: true
}, {
title: 'This is a really long event title that occurs on every year',
type: 'important',
startsAt: moment().startOf('day').add(7, 'hours').toDate(),
endsAt: moment().startOf('day').add(19, 'hours').toDate(),
recursOn: 'year',
draggable: true,
resizable: true
}
];
I would like to retrieve and format the events from my database like the example above, but I'm not sure how to tackle this from my controller.
On the Angular Calendar side, I've read that I can use the angular $http service to load the events, like this:
$http.get('/events').success(function(events) {
//TODO - format your array of events to match the format described in the docs
$scope.events = events; //Once formatted correctly add them to the scope variable and the calendar will update
});
Any help would be greatly appreciated
What you would want to do is create a service that takes care of all the HTTP request/response handling and have your controller consume it to get/save/update data. Something like:
// assuming that you have a REST service endpoint at /events
// create your service that will handle all HTTP interaction for the events resource
app.factory('EventsService', ['$http', function($http) {
return {
getAll: function() {
// fetch all events asynchronously
return $http.get('/events').success(function(response) {
var events = response.data;
// if you need to do any pre-processing of the events first, do it here
// pass your events to the next function in the promise chain.
return events;
}, function(err) {
// handle errors here
// pass your error object down the chain in case other error callbacks are added later on to the promise.
return err;
});
}
};
}]);
app.controller('YourController', ['$scope', 'EventsService', function($scope, EventsService) {
// call the asynchronous service method and add your promise success callback that returns your array of events to be bound to your context.
EventsService.getAll().then(function(evts) {
$scope.events = evts;
}, function(err) {
// do any additional error handling here
});
});

Resources