Skip to content

Repository files navigation

soda-angular

Socrata SODA client for Angular

Installation

npm install soda-angular --save

Also install these dev dependencies:

npm install geojson @types/geojson --save-dev

Usage

  1. Add the SodaClientModule to your module imports:
import{SodaClientModule}from'soda-angular';
...
@NgModule({
...
imports: [
...
SodaClientModule.forRoot()]})exportclassAppModule{}
  1. Create models for your dataset(s), decoated with a @SodaDataset that provides the dataset id:
import{FloatingTimestamp,Location}from'soda-angular';import{SodaDataset}from'soda-angular';
@SodaDataset('8b78-2kux')exportclassDevelopmentPermit{city_file_number: string;permit_type: string;permit_class: string;permit_date: FloatingTimestamp;status: string;description_of_development: string;address: string;legal_description: string;neighbourhood_id: number;neighbourhood: string;zoning: string;location: Location;}
@SodaDataset('rwuh-apwg')exportclassBuildingPermit{row_id: string;permit_number: string;permit_date: FloatingTimestamp;address: string;legal_description: string;neighbourhood: string;job_description: string;building_type: string;construction_value: number;zoning: string;location: Location;}
@SodaDataset('kk4c-7pcv')exportclassLegalParcel{id: number;latitude: number;longitude: number;area: number;geometry: MultiPolygon;}
  1. Extend SodaContext with your own service context. Provide the URL to the Socrata service of your choice via the @SodaHost decorator, and create your SodaResource objects with a dataset models:
import{Injectable}from'@angular/core';import{SodaClient,SodaContext,SodaHost,SodaResource}from'soda-angular';
@Injectable({providedIn: 'root',})
@SodaHost('https://data.edmonton.ca/')exportclassOdpContextextendsSodaContext{publicreadonlydevelopmentPermits: SodaResource<DevelopmentPermit>;publicreadonlybuildingPermits: SodaResource<BuildingPermit>;constructor(sodaClient: SodaClient){super(sodaClient);this.developmentPermits=newSodaResource(DevelopmentPermit,this);this.buildingPermits=newSodaResource(BuildingPermit,this);}}
  1. Inject your Context into your component, and query against it using fluent querying:
import{Component,OnInit}from'@angular/core';import{FloatingTimestamp,Location}from'soda-angular';
@Component({selector: 'permits',templateUrl: './permits.component.html',styleUrls: ['./permits.component.css']})exportclassPermitsComponentimplementsOnInit{publicDevelopmentPermits: DevelopmentPermit[];publicBuildingPermits: BuildingPermit[];constructor(privatecontext: OdpContext){}ngOnInit(){this.context.developmentPermits.where(p=>p.permit_type).equals('Major Development Permit').and(p=>p.permit_date).greaterThan(newFloatingTimestamp('04/23/2020 GMT')).and(p=>p.zoning).not().equals('RF1').orderBy(p=>neighbourhood).observable().subscribe(permits=>this.DevelopmentPermits=permits);this.context.buildingPermits.where(p=>p.permit_date).greaterThan(newFloatingTimestamp('04/23/2020 GMT')).and(p=>p.neighbourhood).equals('DOWNTOWN').or(p=>p.neighbourhood).equals('OLIVER').observable().subscribe(permits=>this.BuildingPermits=permits);}}

Location type queries:

this.context.developmentPermits.location(p=>p.location).withinCircle(newLocation(53.540959,-113.493819),2000));this.context.buildingPermits.location(p=>p.location).withinBox(newLocation(46.883198,-96.798216),newLocation(46.873169,-96.785139)));

Geometry type queries:

import{MultiPolygon,Point}from'geojson';import{GeoJSONUtils}from'soda-angular';this.context.legalParcels.geomery(p=>p.geometry).intersects(GeoJSONUtils.point(-71.099290,-31.518292));this.context.legalParcels.geomery(p=>p.geometry).intersects(GeoJSONUtils.polygon([-113.599831726514,53.458273089013],[-113.600049996812,53.45827360864],[-113.600052949158,53.457932503403],[-113.599845224387,53.457931995732],[-113.599834691275,53.457931970341],[-113.599831726514,53.458273089013]));this.context.legalParcels.geomery(p=>p.latlon).withinPolygon(GeoJSONUtils.multipolygon([[-113.599831726514,53.458273089013],[-113.600049996812,53.45827360864],[-113.600052949158,53.457932503403],[-113.599845224387,53.457931995732],[-113.599834691275,53.457931970341],[-113.599831726514,53.458273089013]]));

Query builders

You can also use query builders for more control (including OR queries):

constbuilder=newSoqlQueryBuilder();.filter(newWhereFilter(newColumn('permit_type'),Comparitor.Equals,newWhereValue('Major Development Permit'),),newWhereOperator(Operator.And),newWhereGroup(newWhereFilter(newColumn('permit_value'),Comparitor.GreaterThan,newWhereValue(2000000),),newWhereOperator(Operator.Or),newWhereGroup(newWhereFilter(newColumn('permit_class'),Comparitor.Equals,newWhereValue('Class B'),)))).offset(20).limit(20).orderBy(newColumn('neighbourhood'));this.context.developmentPermits.get(builder.getQuery()).subscribe(permits=>this.Permits=permits);

Notes

  • This is a work in progress, watch this repository for updates.
  • Heavily inspired by Entity Framework.
  • Filter grouping coming soon.
  • Support for case-insensitive text matches is coming.
  • Support for select-based functions are coming.

Additional Reading

License

See LICENSE.

About

Socrata SODA client for Angular

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages