Monday, August 24, 2020

SQL - Modify Array of JSON

 How to copy one array of JSON object into another array of JSON in SQL. Take this below sample copy array of empIds from one JSON into another JSON


DECLARE  @pArrayOfIntEmps nvarchar(max)='{ "empIds": [' + '1,2'+'] }'

--JSON_Query will return array value from json whereas JSON_VALUE return object value from json

--select JSON_QUERY(@pArrayOfIntEmps,'$.empIds') 

 

DECLARE @info NVARCHAR(max)='{"id":1,"abc":false,"empIds":[3,4] }'

SET @info=  JSON_MODIFY(ISNULL(@info,'{}'),'$.empIds,JSON_QUERY(@pArrayOfIntEmps,'$.empIds'))

select @info

 

--Output {"id":1,"abc":false,"empIds":[1,2] }, this empIds will be replaced by array of int

Thursday, May 14, 2020

How to ignore property conditionally during JSON serialization

Consider i have class Employer, i want serialize this class to json string and need ignore some properties conditionally. For ex: in my example, i want to include address1 and address2 only if it has valid values


  public class Employer
    {
 public int id { get; set; }

        public string name { get; set; }
       
 public string ssn { get; set; }

        public string address1 { get; set; }

        public string address2 { getset; }
   }



Declare some values


Employer employer = new Employer(){ … address1 = "some value", address2 = null };


Now serialize it for json string


var jsonstring = JsonConvert.SerializeObject(employer,
                       Newtonsoft.Json.Formatting.None,
                       new JsonSerializerSettings
                       {
                           
                       });

Here you will get all the properties.

Now lets see how to ignore the properties conditionally, you can choose either one of these options.

Option 1: Use ShouldSerialize property inside class itself like below. But you need add individual shouldSerialize property for each class property.

  public class Employer
    {
 public int id { get; set; }

        public string name { get; set; }
       
 public string ssn { get; set; }

        public string address1 { get; set; }

        public string address2 { get; set; }

        public bool ShouldSerializeaddress1()
        {
            // don't serialize if it is null or empty or add any your custom conditions
            return !string.IsNullOrEmpty(address1);
        }
        public bool ShouldSerializeaddress2()
        {
            // don't serialize if it is null or empty or add any your custom conditions
            return !string.IsNullOrEmpty(address2);
        }

   }


Option 2: Instead creating multiple ShouldSerialize property inside class, we can create ContractResolver and add it in Json serialization as below,

Create Resolver Class,

using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Linq;
using System.Reflection;
...

  public class EmployerShouldSerializeContractResolver : DefaultContractResolver
    {
        public new static readonly EmployerShouldSerializeContractResolver Instance = new EmployerShouldSerializeContractResolver();

        protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
        {
            JsonProperty property = base.CreateProperty(member, memberSerialization);

            if (property.DeclaringType == typeof(Employer))
            {
                property.ShouldSerialize =
                    instance =>
                    {
                        //ignore default values
                        return instance.GetType().GetProperty(member.Name).GetValue(instance, null) != property.DefaultValue;
                    };
            }

            return property;
        }

    }


Include it in JSON serialization,

var jsonstring = JsonConvert.SerializeObject(employer,
                       Newtonsoft.Json.Formatting.None,
                       new JsonSerializerSettings
                       {
                           ContractResolver = new EmployerShouldSerializeContractResolver()
                       });


Friday, April 24, 2020

Angular CLI - Custom Date validator

Angular supports of custom validators. Here i have created custom validator to validate date for template drive forms.

Directive: date-validator.directive.ts


import { AbstractControl, ValidatorFn, FormControl } from '@angular/forms';
import * as moment from 'moment';
import { NG_VALIDATORS, Validator } from '@angular/forms';
import { Directive } from '@angular/core';

// validation function
function validateDateFactory(): ValidatorFn {
  return (c: AbstractControl) => {

    let isValid = moment(c.value, 'M/D/YYYY', true).isValid();

    if (isValid) {
      return null;
    } else {
      return {
        validDate: {
          valid: false
        }
      };
    }
  }
}

@Directive({
  selector: '[validDate][ngModel]',
  providers: [
    { provide: NG_VALIDATORS, useExisting: ValidDateValidator, multi: true }
  ]
})
export class ValidDateValidator implements Validator {
  validator: ValidatorFn;

  constructor() {
    this.validator = validateDateFactory();
  }

  validate(c: FormControl) {
    return this.validator(c);
  }

}


Html:
<input type="text" [(ngModel)]="someDateModal" validDate />