Angular 5 HttpClient Post List to Web Api - always null? - list

The setup is Angular 5 and .net core Web Api. At the controller, model binding always results in null while trying to bind to a complex object.
Code is provided below.
This example is adapted from another SO answer . but its not working for me.
Controller:
[Route("demopost1")]
[HttpPost]
public async Task < IntResultEntity > DemoPostList1([FromBody]DemoPostViewModel payload)
{
return await Task.FromResult(new IntResultEntity { Result = 0 });
}
Models:
public class DemoPostModel {
public string RelationType { get; set; }
public int Weight { get; set; }
}
public class DemoPostViewModel {
public IList<DemoPostModel> SubUnits { get; set; }
}
Client side:
export class DemoPostComponent implements OnInit {
constructor(private demoPostSvc: DemoPostService,
private fb: FormBuilder) { }
demoData: any[]
demoPostForm: FormGroup
submitDemoPost1(form: FormGroup) {
let formModel = form.value;
const payload = {
'subUnits': [
formModel.demoFormArray.map(element => ({
'relationType': element.relationType,
'weight': element.weight
}))
]
};
this.demoPostSvc.demoPost1(payload)
.subscribe(data => {
console.log("Post success.");
}, error => {
console.log("Post failed.");
});
}
ngOnInit() {
this.demoData = [
{ 'relationType': 1, 'weight': 2 },
{ 'relationType': 3, 'weight': 4 },
];
this.demoPostForm = this.fb.group({
demoFormArray: this.populateForm()
});
}
populateForm(): FormArray {
let formFields: any[] = [];
this.demoData.forEach(element => {
formFields.push(this.fb.group({
'relationType': element.relationType,
'weight': element.weight
}));
});
return this.fb.array(formFields);
}
}

Modify DemoPostViewModel to include a constructor like below:
public class DemoPostViewModel
{
public DemoPostViewModel()
{
SubUnits = new List<DemoPostModel>();
}
public IList<DemoPostModel> SubUnits { get; set; }
}

Related

my token sends user_id How I can get it by localStorage in Angular?

I need help trying to figure it out, i am using django as backend and Angular as frontend.
My django backend pass a token so it can be acessed in frontend by login.
login.ts
onLogin() {
this.service.loginUser(this.input).subscribe(
response => {
console.log(response)
this.jwttoken.setToken(response['token']);
this.jwttoken.getItem(response);
this.router.navigate(['dashboard']);
},
error => {
console.log('error', error);
}
i save it in a localstorage that can be acessed on my service
jwttoken service
jwtToken : string
decodedToken: {[key: string]: string}
public storage: Storage;
constructor() {
this.storage = window.localStorage;
}
setToken(token: string){
if (token) {
this.jwtToken = token;
}
}
getItem(key: string) {
if(this.storage){
localStorage.setItem('token',(key));
}
return null;
}
i need to have my user id that i can see on my web browser console.
{"token":"[object Object]","d34330659cba7cf64e8414f83aa6522f55b0f978":"d34330659cba7cf64e8414f83aa6522f55b0f978","[object Object]":"{"token":"d34330659cba7cf64e8414f83aa6522f55b0f978","user_id":1,"email":"admin#admin.com"}"}
this is where i need to access my user id, so i can send it to my html file
export class RegularComponent implements OnInit {
patient_code: any;
number_tumor: any;
tumor_size: any;
tumor_volume: any;
biopsy_date: any;
hp_lote_number: any;
closeResult: string;
userlists: any;
user_id: any;
constructor(private service: SharedService, private modalService: NgbModal, private jwtstorage: JWTTokenServiceService) { }
localstorage = JSON.stringify(this.jwtstorage.storage).replace(/\\/g, "");
ngOnInit() {
// this.getUserlist();
console.log(this.localstorage);
}
// getUserlist() {
// let observable = this.service.getUsersList();
// observable.subscribe((data) => { this.userlists = data; console.log(data); return data; }); }
open(content) {
this.modalService.open(content,{ariaLabelledBy: 'modal-basic-title', size: 'lg'}).result.then((result) => {
this.closeResult = `Closed with: ${result}`;
}, (reason) => {
this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
});
}
private getDismissReason(reason: any): string {
if (reason === ModalDismissReasons.ESC) {
return 'by pressing ESC';
} else if (reason === ModalDismissReasons.BACKDROP_CLICK) {
return 'by clicking on a backdrop';
} else {
return `with: ${reason}`;
}
}
}
I searched all around, and I can't figure it out. Could you explain to me how I can do this?
I just need the user_id of that string that cames from the localstorage. Thank you.

Why is the service not injected into the controller?

I'm trying out AdonisJS, but I'm stuck trying to get a service injected into a controller. No matter what I try, the hs constructor argument in VersionsController remains undefined.
I've also experimented with annotating the VersionController constructor with #inject(['#ioc:Service/HashService']), but with no luck. I'm not sure though if #inject is the right way for Adonis.js v5.
How do I properly inject a service class into a controller?
/providers/AppProvider.ts
import { ApplicationContract } from '#ioc:Adonis/Core/Application'
import HashService from 'App/Services/HashService';
export default class AppProvider {
protected app: ApplicationContract;
constructor(app: ApplicationContract) {
this.app = app;
}
public register() {
this.app.container.singleton('#ioc:Service/HashService', () => {
return new HashService();
});
}
public async boot() {
// IoC container is ready
}
public async ready() {
// App is ready
}
public async shutdown() {
// Cleanup, since app is going down
}
}
/app/Services/HashService.ts
'use strict'
export default class HashService {
async test() {}
}
module.exports = HashService;
app/Controllers/Http/VersionsController.ts
import { HttpContextContract } from '#ioc:Adonis/Core/HttpContext'
import { HashService } from '#ioc:Service/HashService'
export default class VersionsController {
protected hs: HashService
constructor(hs: HashService) {
this.hs = hs;
console.log("hashservice is " + hs);
}
public async get(ctx: HttpContextContract) {
return [
{
id: 1,
title: 'a'
}
]
}
public async put(ctx: HttpContextContract) {
return "PUT";
}
}
.adonisrc.json
{
"typescript": true,
"commands": [
"./commands",
"#adonisjs/core/build/commands/index.js",
"#adonisjs/repl/build/commands"
],
"exceptionHandlerNamespace": "App/Exceptions/Handler",
"aliases": {
"App": "app",
"Config": "config",
"Database": "database",
"Contracts": "contracts"
},
"preloads": [
"./start/routes",
"./start/kernel"
],
"providers": [
"./providers/AppProvider",
"#adonisjs/core"
],
"aceProviders": [
"#adonisjs/repl"
]
}
you can use Adonisjs/fold
simply use the #inject decorator in your services;
example;
import {HttpContextContract} from "#ioc:Adonis/Core/HttpContext";
import UserEditValidator from "App/Validators/UserEditValidator";
import UserRepository from "App/Repository/UserRepository";
import {inject} from "#adonisjs/fold";
#inject()
export default class UserService {
constructor(private userRepository: UserRepository) {
}
async update(ctx: HttpContextContract) {
//do your stuff
}
}
and then in your controller;
import {HttpContextContract} from "#ioc:Adonis/Core/HttpContext";
import UserService from "App/Service/UserService";
import {inject} from "#adonisjs/fold";
#inject()
export default class UserController {
constructor(private userService: UserService) {
}
async edit({ view }){
return view.render('user/edit', {title: 'Edit Profile'})
}
async update(ctx : HttpContextContract){
await this.userService.update(ctx);
return ctx.response.redirect().back()
}
}

Flutter Firebase upload a List of customClass

I want to upload a List of a custom class to the cloud firebase, but I get the error that my custom class is not a subtype of type <dynamic>. Does this happen because it is not possible to upload List of custom classes to firebase? Do I need to create e new collection which than works as the List or is there a other way to work around this problem?
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
//Class for the custom list
class CustomClass {
int id;
String content;
CustomClass({this.id, this.content});
CustomClass.fromMap(Map<String, dynamic> data) {
id = data['id'];
content = data['content'];
}
Map<String, dynamic> toMap() {
return {
'id': id,
'content': content,
};
}
}
//Model which I want to upload with the custom list
class CustomModel {
String name;
List<CustomClass> customList;
CustomModel();
CustomModel.fromMap(Map<String, dynamic> data) {
name = data['name'];
customList = data['customList'];
}
Map<String, dynamic> toMap() {
return {
'name': name,
'customList': customList,
};
}
}
//Page to upload the customModel with the customList
class UploadPage extends StatelessWidget {
CustomModel _customModel = CustomModel();
List<CustomClass> _customList = [CustomClass(id: 1, content: 'UserContent')];
#override
Widget build(BuildContext context) {
return Scaffold(
body: FlatButton(
child: Text('Upload'),
onPressed: () async {
_customModel.name = 'UserName';
_customModel.customList = _customList;
await Firestore.instance
.collection('CustomClass')
.add(_customModel.toMap());
}),
);
}
}
You can use dart: convert to convert your model object into json format i.e Map which you can upload to Firebase.
For this, I have renamed your toMap method to toJson & fromMap methods to fromJson. Also, I have added factory keyword before fromJson methods.
You should also override the toString method to print your objects for testing/debugging.
Your code should look something like this:
//Class for the custom list
class CustomClass {
int id;
String content;
CustomClass({this.id, this.content});
factory CustomClass.fromJson(Map<String, dynamic> data) {
return CustomClass(
id: data['id'],
content: data['content'],
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
'content': content,
};
}
#override
String toString() {
return '${const JsonEncoder.withIndent(' ').convert(this)}';
}
}
//Model wich I want to upload with the custom list
class CustomModel {
String name;
List<CustomClass> customList;
CustomModel({
this.name,
this.customList,
});
factory CustomModel.fromJson(Map<String, dynamic> data) {
List<dynamic> list = data['customList'] ?? [];
final customList = list.map((e) => CustomClass.fromJson(e)).toList();
return CustomModel(
name: data['name'],
customList: customList,
);
}
Map<String, dynamic> toJson() {
return {
'name': name,
'customList': customList?.map((e) => e.toJson())?.toList(),
};
}
#override
String toString() {
return '${const JsonEncoder.withIndent(' ').convert(this)}';
}
}
// Your build method:
CustomModel _customModel = CustomModel();
List<CustomClass> _customList = [CustomClass(id: 1, content: 'UserContent')];
#override
Widget build(BuilContext context) {
return Scaffold(
body: FlatButton(
child: Text('Upload'),
onPressed: () async {
_customModel.name = 'UserName';
_customModel.customList = _customList;
await Firestore.instance
.collection('CustomClass')
.add(_customModel.toJson());
}),
);
}

Angular 2: BehaviorSubject/Subject does not work outside constructor

Hi I need pass the data from one component to another, for this I am using the class BehavorSubject(I tried too with Subject class, but doesnt works for me). This is my code:
Home page has a filter, and when is selected a filter, it called the service and it service should change a variable of homePage
HomePage.ts
#Component({
providers: [PatientService],
})
export class HomePage {
subscription: Subscription;
constructor( public auth: AuthService,
public patientService: PatientService) {
this.subscription = this.patientService.nameGiven.subscribe(
nameGiven => {
this.patientsByElement = nameGiven.toString();
});
------ more code---
}
Filtro.ts
export class FiltroPage {
showFilter(filter : FiltroT): void{
... code ...
clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
this.PatientService.getPatientsByTags(this.token,this.filterSelected);
} , 1000);
}
}
patient-service.ts
import { Subject } from 'rxjs/Subject';
import { Observable ,BehaviorSubject } from 'rxjs/Rx';
#Injectable()
export class PatientService {
nameSource = new BehaviorSubject("asd");
nameGiven = this.nameSource.asObservable();
this.nameSource.next('hi!!!'); //**it works but only in the constructor**
this.nameGiven.subscribe(()=>{
console.log("it changed");
});
getPatientsByTags(token: String, tags: Array<string>){
return new Promise(resolve => {
this.http.get(ConnectionParams.DevEnv + ProceduresNames.TagsByPatient + ProceduresNames.TagIdEtiqueta + tags, options)
.map(res => res.json())
.subscribe(data => {
if(data.data.poAnicuRegistros){
console.log("here")
this.nameSource.next('hi TON :/'); // <-- ***here is the problem. It doesnt work***
}
else
console.log("XX");
resolve( this.data);
});
});
}
}
Finally i didn't use the BehaviorSubject/Subject, i pass the data from the filter to Homepage of this way :
HomePage.ts
public popoverCtrl: PopoverController
//code ...
showFilter(myEvent) {
let popover = this.popoverCtrl.create(FiltroPage, {
showConfirm: (x) => {
//do something with the data received from the filter
}
});
popover.present({
ev: myEvent
});
}
Filter.ts
//code...
params: NavParams;
showConfirm() {// function that return the data to homePage
this.params.get('showConfirm')(this.patientsBytag);
}

How to pass Unit test after implementing ngx-bootstrap/datepicker?

I created independent component with ngx-bootstrap/datepicker on angular-cli project.
Everything works fine but Unit test is failing.
But I am new on Unit Testing, and I tried to test but it saying fails.
Here is Travic-CI build log.
https://travis-ci.org/webcat12345/webcat-black-page/builds/221961698
Here is my project version and code.
#angular/cli: 1.0.0
node: 7.6.0
os: linux x64
#angular/cli: 1.0.0
#angular/common: 4.0.2
#angular/compiler: 4.0.2
#angular/compiler-cli: 4.0.2
#angular/core: 4.0.2
#angular/forms: 4.0.2
#angular/http: 4.0.2
#angular/platform-browser: 4.0.2
#angular/platform-browser-dynamic: 4.0.2
#angular/router: 4.0.2
Template
<datepicker class="well well-sm main-calendar" [(ngModel)]="dt" [minDate]="minDate" [showWeeks]="false" [dateDisabled]="dateDisabled"></datepicker>
Component (sorry for posting full code. it is just sample code from ngx-bootstrap demo)
import { Component, OnInit } from '#angular/core';
import * as moment from 'moment';
#Component({
selector: 'app-sidebar-datepicker',
templateUrl: './sidebar-datepicker.component.html',
styleUrls: ['./sidebar-datepicker.component.scss']
})
export class SidebarDatepickerComponent implements OnInit {
public dt: Date = new Date();
public minDate: Date = void 0;
public events: any[];
public tomorrow: Date;
public afterTomorrow: Date;
public dateDisabled: {date: Date, mode: string}[];
public formats: string[] = ['DD-MM-YYYY', 'YYYY/MM/DD', 'DD.MM.YYYY',
'shortDate'];
public format: string = this.formats[0];
public dateOptions: any = {
formatYear: 'YY',
startingDay: 1
};
private opened: boolean = false;
constructor() {
(this.tomorrow = new Date()).setDate(this.tomorrow.getDate() + 1);
(this.afterTomorrow = new Date()).setDate(this.tomorrow.getDate() + 2);
(this.minDate = new Date()).setDate(this.minDate.getDate() - 1000);
(this.dateDisabled = []);
this.events = [
{date: this.tomorrow, status: 'full'},
{date: this.afterTomorrow, status: 'partially'}
];
}
ngOnInit() {
}
public getDate(): number {
return this.dt && this.dt.getTime() || new Date().getTime();
}
public today(): void {
this.dt = new Date();
}
public d20090824(): void {
this.dt = moment('2009-08-24', 'YYYY-MM-DD')
.toDate();
}
public disableTomorrow(): void {
this.dateDisabled = [{date: this.tomorrow, mode: 'day'}];
}
// todo: implement custom class cases
public getDayClass(date: any, mode: string): string {
if (mode === 'day') {
let dayToCheck = new Date(date).setHours(0, 0, 0, 0);
for (let event of this.events) {
let currentDay = new Date(event.date).setHours(0, 0, 0, 0);
if (dayToCheck === currentDay) {
return event.status;
}
}
}
return '';
}
public disabled(date: Date, mode: string): boolean {
return ( mode === 'day' && ( date.getDay() === 0 || date.getDay() === 6 ) );
}
public open(): void {
this.opened = !this.opened;
}
public clear(): void {
this.dt = void 0;
this.dateDisabled = undefined;
}
public toggleMin(): void {
this.dt = new Date(this.minDate.valueOf());
}
}
Test Code
import { async, ComponentFixture, TestBed } from '#angular/core/testing';
import { CUSTOM_ELEMENTS_SCHEMA } from '#angular/core';
import { DatepickerModule } from 'ngx-bootstrap/datepicker';
import { SidebarDatepickerComponent } from './sidebar-datepicker.component';
describe('SidebarDatepickerComponent', () => {
let component: SidebarDatepickerComponent;
let fixture: ComponentFixture<SidebarDatepickerComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ SidebarDatepickerComponent ],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
imports: [DatepickerModule.forRoot()]
})
.compileComponents();
}));
beforeEach(async() => {
fixture = TestBed.createComponent(SidebarDatepickerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
Please help me to figure out this issue.
Thank you!
1) Use NO_ERRORS_SCHEMA instead of CUSTOM_ELEMENTS_SCHEMA because:
CUSTOM_ELEMENTS_SCHEMA will allow:
any non-Angular elements with a - in their name,
any properties on elements with a - in their name which is the common rule for custom
but your component without -(datepicker)
NO_ERRORS_SCHEMA will allow any property on any element
TestBed.configureTestingModule({
declarations: [ SidebarDatepickerComponent ],
schemas: [NO_ERRORS_SCHEMA],
imports: [DatepickerModule.forRoot()]
})
2) Another option is importing FormsModule
TestBed.configureTestingModule({
declarations: [ SidebarDatepickerComponent ],
imports: [DatepickerModule.forRoot(), FormsModule]
})