Breeze DataType.parseDateFromServer in the TypeScript project - breeze

I am using TempHire Angular 2 as the reference architecture in my current project. I am facing very same issue as in the following Stackoverflow thread i.e unable to save date value in SQL server as input by the user due to UTC issue.
breezejs: date is not set to the right time
In my Angular2/Typescript project, where I can do the changes as described in the above URL. Typescript syntax is appreciated.
Note: I have already included momentJs in my project.

Please refer.
https://github.com/Breeze/temphire.angular/issues/12
if anyone has similar requirements, I have done the below.
Inside prepare()
{
.........
.........
DataType.parseDateFromServer = this.parseDateAsMoment;
.........
.........
}
parseDateAsMoment(source: any): Date{
var date = moment.utc(source, 'YYYY-MM-DD HH-mm-ss');
return date.toDate();
}
In Angular component, ondatechanged event of MyDatePicker.
onDateFromChanged(event: IMyDateModel) {
if (event.formatted !== '') {
var newDate = moment.utc(new Date(event.jsdate).toLocaleDateString()).format('YYYY-MM-DD HH-mm-ss')
var newDate2 = moment.utc(newDate, 'YYYY-MM-DD HH-mm-ss');
this.model.dateFrom = newDate2.toDate();
}
}
Only then the date input stores correctly in SQL Server datetime column.

Related

Unable to display datetime correctly in iOS/Safari using ionic2/angular2

Hi im facing a weird issue here im getting dynamic data in that im also getting the date and time and im displaying it in html using date pipe in chrome/android it is working good but when i check ios/Safari it is showing time difference
below is my json data im consuming
FromCurrentDate: "2018-01-05T00:00:00"
FromPreviousDate: "2018-01-04T00:00:00"
ToCurrentDate: "2018-01-05T14:00:53.137"
ToPreviousDate: "2018-01-04T14:00:53.137"
im displaying the date like this and
in chrome/android it is displaying like this
in Ios/safari it is displaying like this
in the template im using the code below
Currrent {{singleTable[0].FromCurrentDate|date: 'dd/MM/yyyy,h:mm:ss a'}} to {{singleTable[0].ToCurrentDate|date: 'dd/MM/yyyy,h:mm:ss a'}}
how can i solve this time difference issue?
The issue you are facing is caused by the Intlapi because DatePipe for Angular 2 Release is working fine only for FireFox and Chrome with custom format strings.
it Doesn't work on Safari due to lack of Intl. so as a temporary work around is to include the Intl polyfill
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.en"></script>
Solution 2
You can use the moment.js which can format your required date as follows
moment(singleTable[0].FromCurrentDate).format("dd/MM/yyyy,h:mm:ss a")
Update 1
In latest angular they have removed the Intl api , and for this you need to update to the angular 5 , reference
Update 2
Here is a plunker using MomentJs in angular flavor, i added your date format but didn't tested in safari tested in chrome,
In ios/mac date filter doesn't work, so use moment.js for this.
I have tried lot of stuff but I was able to do best in moment.js
like: I created a pipe
<span>{{ActionDate | dateTimeFormatFilter : "MMM DD, YYYY"}}</span>
#Pipe({name: "dateTimeFormatFilter"})
#Injectable()
export class DateTimeFormatPipe implements PipeTransform {
transform(date: any, format: string): any {
if (date) {
return moment(date).format(format);
}
}
}
I ran into the same issue on safari on desktop and safari/chrome on iPhone.
It works on safari or mostly all browsers when the date object is used as the value. (DatePipe)
I resolved the same issue by adding a custom pipe to convert the date-time string into date object and then the date pipe works as expected.
Component
someDate1 = "2019-09-01 12:02:14";
someDate2 = "2019-09-01";
someDate3 = "2019-09-01 00:00:00";
Template
{{ someDate1 | toDateObj | date:'MM-dd-yyyy h:mm a' }}
Here is the toDateObj custom pipe I added.
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({
name: 'toDateObj'
})
export class ToDateObjPipe implements PipeTransform {
transform(value: any): any {
if (value) {
if (value.toString().indexOf(' ') === -1) {
value = value + ' 00:00:00';
}
const temp = value.toString().replace(' ', 'T');
return new Date(temp);
} else {
return null;
}
}
}
For me this works on Safari and on Chrome:
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({
name: 'customDate'
})
export class DatePipe implements PipeTransform {
transform(value: string): string {
let dd = value.substr(8, 2);
let MM = value.substr(5, 2);
let yyyy = value.substr(0, 4);
let date = `${dd}.${MM}.${yyyy}`;
return `${date}`;
}
}
I had a bug rendering views on Safari when chrome was ok. Later after debugging I found that pipe | date was a problem. So I made custom one. All answers up are great but importing moment library seems like a big file IMHO.
Just make this class export, make a module and declare it there(also export it) and use as example: {{_question.created_at | toDateObj: 'dd.MM.yyyy'}}
Hope it helps someone

Script does not trigger on FormSubmit: Remove Duplicates in Google Sheet of Google Form responses based on column

I am trying to remove older duplicate form responses based on a column using the following code.
The credit for the code goes to: http://www.jacorre.com/tutorial/remove-duplicate-rows-google-spreadsheets/
The code in my script is:
function removeDuplicates() {
var ss = SpreadsheetApp.getActiveSpreadsheet(),
responses = ss.getSheetByName('Name of Source Sheet'),
range = responses.getDataRange(),
numRows = range.getNumRows()-1,
data = range.getValues(),
columnHeadings = [data[0]],
newData = [];
for (var i=numRows; i>0; i--) {
var row = data[i],
duplicate = false;
for (var j in newData) {
if (row[4] == newData[j][4]) {
duplicate = true;
// [4] is the column number from the 1st column. the above would be 1 + 4 = 5th column
}
}
if (!duplicate) {
newData.push(row);
}
}
var final = ss.getSheetByName('Name of Destination Sheet');
if (!final) {
var final = ss.insertSheet('Name of Destination Sheet');
}
final.clearContents();
final.getRange(1,1,1,columnHeadings[0].length).setFontWeight('bold').setValues(columnHeadings);
final.getRange(2, 1, newData.length, newData[0].length).setValues(newData);
}
This has been set to trigger on Form Submit. It works well on new form submissions.
However, when an existing response is edited using 'Form Edit URL' from: https://webapps.stackexchange.com/questions/89551/show-url-used-to-edit-responses-from-a-google-form-in-a-google-spreadsheet-by-us/89566 the values are not updated into the new sheet.
But if the function is run manually the updated row is updated to the new sheet.
How can I sort this problem? Any help will be appreciated. Thank you.
From my own answer posted at Web Applications SE.
I just did a test and found that the on form submit event it's not
being triggered when a response is edited.
I'm not sure if the on form submit trigger is working as intended, if
the above is due to a bug or to a glitch. To be sure, post an issue to
the Google Apps Script Issue
Tracker.
As a workaround, instead of using the on form submit event, use
another way to run your script, like a time-drive trigger.
References
Custom menus in Google Apps - Google Apps Script Guides
Simple or installable triggers - Google Apps Script Guides
Google Apps Script Support

Ionic Prepopulated Database with Antair Cordova SQLitePlugin [help request]

____ INTRO
Hello everyone, first of all, three clarifications:
My english is not good, so I beg your pardon in advance for my mistakes,
I'm a newbie so forgive me for inaccuracies,
I have previously searched and tried the solutions I found on the internet but still I can not solve the problem of embedding a prepopulated database.
____ THE GOAL
I want to develop an app for iOS and Android with a prepopulated database.
Just for example, the database consists of 15.000 records each one made of three key-value pair (id, firstname and lastname).
___ WHAT I DID
Steps:
ionic start myapp blank
cd myapp
ionic platform add ios
ionic platform add android
Then I created an sqlite database for testing purpose, named mydb.sqlite, made of one table people containing two id, firstname, lastname records.
I decided to use the following plugin: https://github.com/Antair/Cordova-SQLitePlugin
That's because it can be installed with cordova tool.
ionic plugin add https://github.com/Antair/Cordova-SQLitePlugin
(Alert: I think that the instructions on the website show an incorrect reference - "cordova plugin add https://github.com/brodysoft/Cordova-SQLitePlugin" - which refers to another plugin).
Then, following the instructions on the plugin website, I copied the database to myapp/www/db/ so that it can now be found at myapp/www/db/mydb.sqlite
I modified the index.html including the SQLite plugin just after the default app.js script:
<!-- your app's js -->
<script src="js/app.js"></script>
<script src="SQLitePlugin.js"></script>
I also write some lines of code in index.html file to show a button:
<ion-content ng-controller="MyCtrl">
<button class="button" ng-click="all()">All</button>
</ion-content>
Finally I had modified ./js/app.js:
// Ionic Starter App
var db = null;
angular.module('starter', ['ionic' /* What goes here? */ ])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// some predefined code has been omitted
window.sqlitePlugin.importPrepopulatedDatabase({file: "mydb.sqlite", "importIfExists": true});
db = window.sqlitePlugin.openDatabase({name: "mydb.sqlite"});
}); // $ionicPlatform.ready
}) // .run
.controller('MyCtrl', function($scope){
$scope.all = function(){
var query = "SELECT * FROM people";
// I don't know how to proceed
}; // $scope.all
}); // .controller
___ THE PROBLEM
I don't know how to proceed in the controller section to query all the records (just an example of query) and show the results in the console.log.
I think that the following code must be completed in some way:
angular.module('starter', ['ionic' /* What goes here? */ ])
And also the code inside controller section must be completed:
$scope.all = function(){
var query = "SELECT * FROM people";
// I don't know how to proceed
}; // $scope.all
___ FINAL THANKS
Thank you in advance for the help you will give to me.
So this guy's code has helped a lot to encapsulate my DAL. I highly recommend that you use he's code pretty much verbatim.
https://gist.github.com/jgoux/10738978
You'll see he has the following method:
self.query = function(query, bindings) {
bindings = typeof bindings !== 'undefined' ? bindings : [];
var deferred = $q.defer();
self.db.transaction(function(transaction) {
transaction.executeSql(query, bindings, function(transaction, result) {
deferred.resolve(result);
}, function(transaction, error) {
deferred.reject(error);
});
});
return deferred.promise;
};
Let's break this down a bit. The query function takes a query string (the query param) and a list of possible bindings for ? in a query like "SELECT * FROM A_TABLE WHERE ID = ?". Because he's code is a service, the self value points to the service itself for all future invocations. The function will execute a transaction against the db, but it returns a promise that is only fulfilled once the db comes back.
His service provides a second helper function: fetchAll.
self.fetchAll = function(result) {
var output = [];
for (var i = 0; i < result.rows.length; i++) {
output.push(result.rows.item(i));
}
return output;
};
fetchAll will read the rows in their entirety into an array. The result param for fetchAll is the result variable passed in the query function's promise fulfillment.
If you copy and paste his code into your service file, you now have a bonafide DB service. You can wrap that service up in a DAL. Here's an example from my project.
.service('LocationService', function ($q, DB, Util) {
'use strict';
var self = this;
self.locations = [];
self.loadLocked = false;
self.pending = [];
self.findLocations = function () {
var d = $q.defer();
if (self.locations.length > 0) {
d.resolve(self.locations);
}
else if (self.locations.length === 0 && !self.loadLocked) {
self.loadLocked = true;
DB.query("SELECT * FROM locations WHERE kind = 'active'")
.then(function (resultSet) {
var locations = DB.fetchAll(resultSet);
self.locations.
push.apply(self.locations, locations);
self.loadLocked = false;
d.resolve(self.locations);
self.pending.forEach(function (d) {
d.resolve(self.locations);
});
}, Util.handleError);
} else {
self.pending.push(d);
}
return d.promise;
};
})
This example is a bit noisy since it has some "threading" code to make sure if the same promise is fired twice it only runs against the DB once. The general poin is to show that the DB.query returns a promise. The "then" following the query method uses the DB service to fetchAll the data and add it into my local memory space. All of this is coordinated by the self.findLocations returning the variable d.promise.
Yours would behalf similarly. The controller could have your DAL service, like my LocationService, injected into it by AngularJS. If you're using the AngularJS UI, you can have it resolve the data and pass it into the list.
Finally, the only issue I have with the guy's code is that the db should come from this code.
var dbMaker = ($window.sqlitePlugin || $window);
The reason for this is that the plugin does not work within Apache Ripple. Since the plugin does a fine job mirroring the Web SQL interface of the browser, this simple little change will enable Ripple to run your Ionic Apps while still allowing you to work your SQLite in a real device.
I hope this helps.

Phonegap Calendar plugin is asking for calendarName in findAllEventsInNamedCalendar method

I am using calendar plugin to fetch all the events from iOS native calendar.
https://github.com/EddyVerbruggen/Calendar-PhoneGap-Plugin
I am trying to use the below method for that.
var calendarName = "iCal";
window.plugins.calendar.findAllEventsInNamedCalendar(calendarName,success,error);
When I am running the application, and trying to fetch all the events, it is showing the below error.
"Error: could not find calendar."
$("#create").click(function(){
window.plugins.calendar.createEvent(title,location1,notes,startDate,endDate,success,error);
});
$("#find").click(function(){
window.plugins.calendar.findEvent(title,location1,notes,startDate,endDate,success,error);
});
$("#deleteAll").click(function(){
window.plugins.calendar.deleteEvent(title,location1,notes,startDate,endDate,success,error);
});
Create events, find events and Delete is working.
Can any one help to find out what should be the value of "calendarName" variable to find the value from iOS native database ?
you are just running full code which is given to github right
first you have to create calendar then you can find it. in below sequence once calendar is created then in second it will be deleted too.
// prep some variables
var startDate = new Date("September 24, 2013 13:00:00");
var endDate = new Date("September 24, 2013 14:30:00");
var title = "My nice event";
var location = "Home";
var notes = "Some notes about this event.";
var success = function(message) { alert("Success: " + JSON.stringify(message)); };
var error = function(message) { alert("Error: " + message); };
var calendarName = "iCal";
// create a calendar (iOS only for now)
window.plugins.calendar.createCalendar(calendarName,success,error);
// create in a named calendar (iOS only for now)
window.plugins.calendar.createEventInNamedCalendar(title,location,notes,startDate,endDate,calendarName,success,error);
Now you can check below events
// find (iOS only for now)
window.plugins.calendar.findEvent(title,location,notes,startDate,endDate,success,error);
// find all events in a named calendar (iOS only for now)
window.plugins.calendar.findAllEventsInNamedCalendar(calendarName,success,error);
the PhoneGap 2.x version does not support the named calendar. Maybe you are using the 2.x version of the plugin with the 3.x readme?
Please refer to the 2.x readme: https://github.com/EddyVerbruggen/Calendar-PhoneGap-Plugin/tree/pre-3.0

Grails - How Do I Show Version And Build Date/Time In My Application

I'd like to know if there is a way to display the version and build date at the top of my Grails application.
Edit: I should have said I'm looking for the Date/Time the app was built.
In your main template, or wherever.
<p style="float:right">Server version: <%=ApplicationHolder.application.metadata['app.version']%></p>
You can use <g:if env="..."> to limit by environments if you wish.
Build date is trickier, and probably doesn't mean anything. Do you never build twice on the same day? Same hour? I'm sticking the svn revision in my application version before the build to identify builds, as such:
_Events.groovy
eventWarStart = { type ->
addSvnRevisionToAppVersion()
}
private def addSvnRevisionToAppVersion() {
try {
DAVRepositoryFactory.setup();
SVNRepositoryFactoryImpl.setup();
FSRepositoryFactory.setup();
SVNClientManager clientManager = SVNClientManager.newInstance();
SVNWCClient wcClient = clientManager.getWCClient();
File baseFile = new File(basedir);
SVNInfo svninfo = wcClient.doInfo(baseFile, SVNRevision.WORKING);
def svnRevision = svninfo.getRevision().number;
String oldVersion = metadata.'app.version'
String newVersion
if (oldVersion.matches(/.*\.r\d+/)) {
newVersion = oldVersion.replaceAll(/\.r\d+/, ".r${svnRevision}");
}
else {
newVersion = oldVersion + ".r${svnRevision}".toString()
}
metadata.'app.version' = newVersion
metadata.persist()
}
catch (SVNException ex) {
println "**************** SVN exception **************"
println ex.getMessage();
}
}
Note that instead of appending svn revision, you could just append new Date() to get the build date.
i havent tried it my self but there is something like
grails set-version 20110101-3
def version = grailsApplication.metadata['app.version']
for more info refer to documentation
Any one looking for the solution for grails 3. It can be done by configuring the buildProperties task
buildProperties {
inputs.property("info.app.build.date", new Date().format('yyyy-MM-dd HH:mm:ss'))
}
<g:meta name="info.app.build.date"/>
See Adding build date and other custom info to war

Resources