Angular resource converting Date object into String while fetching data - angularjs

I am using Angular resource for ajax operations in my project. I have some date fields i am converting them into JavaScript Date() Object at server when i am fetching the data, i am using Node js (Express js ) at server side. At client side i require this date object for uib datepicker. My Server code for date conversion is:
findAndFormatDate: function (data) {
Object.keys(data).forEach(function (key) {
if (key.indexOf("date") !== -1 || key.indexOf("Date") !== -1) {
data[key] = new Date(data[key]);
if (data[key] instanceof Date) {
console.log("Yes it is a date, and the type is ", typeof data[key]);
}
}
});
return data;
}
and at server console i am getting the message Yes it is a date, and the type is object, but when i am getting this data at client side and checking the typeof this date field then it is showing string and i need to again convert it at client side then it is working properly, i am not able to understand why it requires two time conversion, i want to convert in only at server side so how can i avoid the conversion at client side?

Related

How to enable Time Zone support for ASP.NET Core API?

I've got a mobile app and a Web application that consumes an ASP.NET Core 3.x WEB API that uses SQL Server as it's datastore. The client applications can be in different Time Zones.
The dilemma I'm facing is filtering records with a date range.
For instance, I've got a table called 'PaymentTransaction' that consists of a column 'TransactionDateTime' that is of type DateTimeOffset.
Entity object:
[Table("PaymentTransaction")]
public class PaymentTransaction
{
public DateTimeOffset TransactionDateTime { get; set; }
}
API endpoint for creating the records: PaymentRequestDto content excluded for brevity
[HttpPost, Route("Create")]
public async Task<ActionResult> Create([Required] PaymentRequestDto)
{
await _context.PayoutTransactions.AddAsync(new PaymentTransaction()
{
TransactionDateTime = DateTimeOffset.UtcNow;
});
await _context.SaveChangesAsync();
return Ok();
}
API endpoint for filtering the records:
[HttpGet, Route("GetRangeSample/{startDateTime}/{endDateTime}")]
public async Task<ActionResult> GetRangeSample([Required] DateTimeOffset startDateTime, [Required] DateTimeOffset endDateTime)
{
var result = await _context.PaymentTransactions.Where(x => x.TransactionDateTime >= date && x.TransactionDateTime <= date).ToListAsync();
return Ok(result);
}
JavaScript Client requesting filtered records;
var startDate = new Date();
var endDate = new Date();
endDate.setDate(endDate.getDate() + 7)
$.ajax({
type: "get",
url: "http://localhost:55724/api/GetRangeSample",
data:{
startDateTime: startDate,
endDateTime: endDate
},
success: function(response){
console.log(response);
},
error: function(error)
{
console.log(error);
}
});
If I'm to filter records for a given date range, let's say 02-21-2022 to 02-28-2022. some records are not returned.
What am I doing wrong? How do you normally go about saving a DateTimeOffset and retrieving records based on a date filter?
Presuming you mean to have the user select entire days in their time zone, the issue is in the way you've created the start and end dates in your JavaScript code. Keep in mind that a JavaScript Date object represents a point in time (not a whole date), and that new Date() gives the point in time that is now.
Thus, you should probably create your start and end dates like this instead, so they are inclusive of the entire day rather than just the remainder of the day after the time ran the code.
var startDate = new Date(); // get the current "now"
startDate.setHours(0,0,0,0); // adjust to the start of the local day
var endDate = new Date(startDate); // copy to another instance
endDate.setDate(endDate.getDate() + 7); // advance 7 days

im trying to update database record with function return Ionic, Back&

Hi I'm trying to update my database with function that returns a number
$scope.sum = function()
{
return $scope.inp + $scope.points;
};
this function will update the record in object points, column name and id 1:
$scope.addPoint = function() {
PointService.addPoint($scope.sum, 1)
.then(function(result) {
$scope.inp = 0;
getMyPoints();
});
}
addPoint = function(id,points)
{
return $http.put(getUrlForId(1),points,name);
}
the error is: Error details: Cannot convert type 'int' to 'System.Collections.Generic.Dictionary'
the data type of the field is Float.
Any idea what is wrong with the code?
you are passing function reference to PointService.addPointer(),
use this:
$scope.addPoint = function() {
PointService.addPoint($scope.sum(), 1) // NOT PointService.addPoint($scope.sum, 1)
.then(function(result) {
$scope.inp = 0;
getMyPoints();
});
}
this will execute your function and pass the output (id parameter) to addPoint function, further, for more safe side, you can return Number from $scope.sum() i.e.
$scope.sum = function()
{
return Number($scope.inp + $scope.points);
};
This looks like an issue with how you're contacting Backand. You use the following code to send your points over:
addPoint = function(id,points)
{
return $http.put(getUrlForId(1),points,name);
}
This is an older version of calling the Backand API that is manually constructing a PUT request, and putting "points" and "name" as the "Data" and "config" parameters to $http. With an object update via PUT, you'll need to provide the updates as an object. So if you wanted to update the points and the name of the object (and I'm doing some assuming based upon what I can tell from the code snippet above), you'd need to encapsulate these properties in an object that has the following general format:
{
"field_name_1":"new value_1",
"field_name_2":"new value_2",
etc ...
}
This should then be sent as the body of the request. So, for your code, change it to the following and see if this helps:
addPoint = function(id,points)
{
return $http.put(getUrlForId(1),{points: points, name: name});
}
To give more info on why you're seeing this particular error, Backand is depending on this JSON format in the body. Our platform should definitely do more validation (and I'll create a ticket for the devs to handle non-conforming input more gracefully), but at the moment we simply take the body of the request, convert it to a dictionary object, then begin the requested operation. As your code above sends only "1.0" as the body, this fails the conversion into a dictionary, causing the stack exception and the issue you are seeing.
As a note, we offer a new SDK that encapsulates these HTTP methods, performing the authentication header generation and HTTP messaging for you, providing promises to handle responses. You can find it on our Github page at https://github.com/backand/vanilla-sdk. To make the same call using the new SDK, the code would resemble the following:
backand.object.update("your object name", 1, {name: name, points: points})
.then(function(response){
console.log(response.data);
});

How to keep date from client saved in MongoDB as date?

I'm using Node.js and Angular.js for a web project. I understand that date is saved as date if it's created on server using new Date() (e.g. 2015-04-08 04:15:18.712Z shown in Robomongo as Date type). However, if the date is created on client using new Date(), it is then saved as a string (e.g. 2015-04-07T04:58:12.771Z shown in Robomongo as String type), because it becomes a string through node API. How to make it save as a Date instead of String?
UPDATE:
This is what I got based on Jason Cust's input. In node's server.js specify the reviver option as follows:
app.use(bodyParser.json({ reviver: function(key, value) {
if ( typeof value === 'string' && value.length === 24) {
if (value.match(/^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d.\d\d\dZ$/)){
return new Date(value);
}
}
return value;
}}));
This will automatically converts all date strings to date objects when data is sent from client to server.
If you want to do the same thing for the Angular.js client, I found a good blog by Andrew Davey Automatic JSON date parsing with AngularJS
I am going to assume you are using JSON to send the date from your Angular app to your Node app. The JSON spec doesn't reconstitute a Date object so you will have to do it yourself first before inserting it into MongoDB.
Example:
// simulate JSON from HTTP request
var json = JSON.stringify({date: new Date()});
console.log(json);
// outputs: '{"date":"2015-04-08T04:50:04.252Z"}'
var obj = JSON.parse(json);
console.log(obj);
// outputs: { date: '2015-04-08T04:50:04.252Z' }
// reconstitute Date object
obj.date = new Date(obj.date);
console.log(obj);
// outputs: { date: Wed Apr 08 2015 00:50:04 GMT-0400 (EDT) }

Server Side Error validation

In my application I am doing client side and server side validation. Client side validation is pretty easy and user will not be able to click on the submitForm button. But suppose the zip code entered does not match with the order number and server is giving me error in 200 response in angular $http call promise. How can I show the server side error and maintain my validation ?
{"result":{"success":false,"code":null,"message":"The entered Zip does not match with Order"},"errors":
[]
Might not be the exact answer but could help :
1) On the server side if there are errors you should first stop the script from reaching to database.
2) Populate error messages on the server side in an array in the form of associative array, which can contain field name as key and error message as value. Later send the array to client side in JSON format.
3) On the client side loop through the JSON object to initialise the scope variables that will contain error messages per field.
May be in the format : serverErrors.fieldName.error = 'Error Message from server'
This should be a scope object. And the same object should be rendered on the template per field. So that when you loop through your JSON and assign error messages to each field it will show up in template. As Angular has two way binding.
This way you will be able to handle custom server side validations and show errors on client side. And this is possible not just in theory we have implemented this approach in one of our projects.
Hope that helps :)
I think you can try
$http.post('URL', { "ID": ID }).success(function (resultData) {
if (results.result.success) {
alert("scuess!");
$window.location.href = "/";
}
else {
alert(results.result.message)
}
});

Can I customize my AngularJS application to display local times?

I am using an ASP.NET MVC / ASP.NET Web API back-end for my application. When a user updates data the time is recorded like this:
public HttpResponseMessage PutContent(int id, Content content)
{
if (id != content.ContentId)
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
try
{
content.ModifiedDate = DateTime.Now;
content.ModifiedBy = User.Identity.GetUserId();
_uow.Contents.Update(content);
_uow.Commit();
return Request.CreateResponse(HttpStatusCode.OK, content);
}
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
}
}
When the user looks at the modified time they see what I assume is the server time. Is there a way that I can allow them to see the local time that the change was made?
Note that already I do some formatting but I am not sure if there is a way that I can convert the date and have this matched up with my local users who could be in any location:
<input disabled="disabled" type="text"
value="{{modal.data.modifiedDate | date:'MM/dd/yy HH:mm'}}" />
To start with it is always better to save the dates on server in UTC. So on the server use the method DateTime.UtcNow.
And while sending the data to client, if you are not custom formatting the date, i believe the date send contains the timezone information as well. AngularJS can handle that correct using date filter. See this fiddle http://jsfiddle.net/jHSLe/1/
Assuming the date you are getting is in UTC, you can use the excellent Moment.js to easily convert it to local time as described here:
http://momentjs.com/docs/#/manipulating/local/

Resources