Why JSON response is null while using Repository class instead of direct ApiProvider class in flutter? - dart

I am trying to parse json from an Api. Here is my ApiProvider class :
class ArticleApiProvider {
String articleUrl = "api";
List<Article> articleList = [];
Future<List<Article>> getArticles() async {
var response = await http.get(articleUrl);
if (response.statusCode == 200) {
var data = json.decode(response.body);
articleList = ApiResult.fromJson(data).articles;
return articleList;
} else {
print("Error");
}
}
}
Here is the Repository class :
class ArticleRepository {
ArticleApiProvider articleApiProvider = ArticleApiProvider();
Future<List<Article>> getTheArticles() {
articleApiProvider.getArticles();
}
}
In main.dart I am getting the json reponse by using ArticleApiProvider :
ArticleApiProvider articleApiProvider = ArticleApiProvider();
articleApiProvider.getArticles();
But if I use the repository class, I am getting null :
ArticleRepository aricleRepository = ArticleRepository();
aricleRepository.getTheArticles():
What's the wrong here?

Related

TypeScript After setup innerHTML in class method parent class make constronted again

Explanation :
I have class ConnectorClient :
class ConnectorClient {
private webSocketController;
private popupForm: HTMLDivElement;
constructor(config: EngineConfig) {
this.popupForm = byId("popup") as HTMLDivElement;
this.webSocketController = new WebSocket(config.getRemoteServerAddressControlller());
this.webSocketController.onopen = this.onOpen;
this.webSocketController.onclose = this.onClose;
this.webSocketController.onmessage = this.onMessage;
this.webSocketController.onerror = this.onError;
// window.WWW = this;
this.showRegisterForm();
}
public showRegisterForm() {
const myInstance = this;
fetch("./templates/register.html", {
headers: htmlHeader,
}).
then(function (res) {
return res.text();
}).then(function (html) {
// console.warn(html);
myInstance.popupForm.innerHTML = html;
byId("login-button").addEventListener("click", myInstance.registerUser, false);
byId("forgotPassword").addEventListener("click", myInstance.ForgotPassword, false);
});
}
public registerUser = (e) => {
const localEmail: string = (byId("login-user") as HTMLInputElement).value;
const localPassword: string = (byId("login-pass") as HTMLInputElement).value;
if (validateEmail(localEmail) !== null) {
byId("error-msg-reg").style.display = "block";
byId("error-msg-reg").innerText = validateEmail(localEmail);
}
if (validatePassword(localPassword) === false) {
byId("error-msg-reg").style.display = "block";
byId("error-msg-reg").innerText += "Password is not valid! length!";
}
if (validateEmail(localEmail) === null && validatePassword(localPassword) === true) {
const userData: IUserRegData = {
email: localEmail,
password: localPassword,
};
let localMsg = { data: { action: "REGISTER", userRegData: userData } };
this.sendObject(localMsg);
localMsg = null;
}
}
In any situation when i call this method class i get loaded again with error on getElementById etc..!
What to do ?
Too see full code look at :
Opensource project:visual ts game engine
Strange is change on page url in: app.html?
Char ? is come from nowhere!

Angular 2 HTTP Post: Cannot get and use response object

I am currently working on an Angular 2 project that uses RESTful as the back end.
Here is a short scenarior that can help me ask my question.
When a user Logs in, I want to redirect to a profile/order page that displays some user details.
In order to achieve this, I have a Register.ts
and in here my code looks like this.
export class RegisterService{
public isLoggedIn:boolean;
public userDetails:any;
public newUser = new User("","","",null);
constructor(private _http: Http){
this.isLoggedIn = false;
}
Register(data:any) {
const body = JSON.stringify(data);
// console.log(data);
this.userDetails = data;
// console.log("userdets: "+this.userDetails.username);
const headers = new Headers();
headers.append('Content-Type', 'application/json');
return this._http.post(`http://192.168.20.17:8080/webshop/api/user/create?username=`+data.username+`&password=`
+data.password+`&email=`+data.email+`&city=`+data.city+`&housenumber=`+data.housenumber+
`&street=`+data.street, body, {headers: headers}
);
}
Login(data:any):Observable<any>{
const body = JSON.stringify(data);
// console.log(data);
const headers = new Headers();
headers.append('Content-Type', 'application/json');
return this._http.post(`http://192.168.20.17:8080/webshop/api/user/login?username=`
+data.username+`&password=`+data.password, body,{headers:headers})
.map((res:Response)=> JSON.stringify(res));
// console.log(this.newUser);
}
And then in my sign-in.component.ts, I have methods that uses this service as shown below
onLogin(_username:string, _password:string)
{
const data = {
username:_username,
password:_password,
}
this._registerService.Login(data)
.subscribe(
data=> resolve(data.json())
)
console.log(this.response);}
onPost(username:string, email:string, password:string, housenumber:string, street:string, city:string)
{
const data = {
username:username,
email:email,
password:password,
housenumber:housenumber,
street:street,
city:city
}
if (data == null)
this.isValid == false;
else {
this.isValid == true;
this._registerService.Register(data).subscribe(
data=> this.response = JSON.stringify(data),
error => console.log(error)),
data=>console.log(data);
localStorage.setItem('user', JSON.stringify(data)
);
if(localStorage.getItem("user") != null) {
this._registerService.isLoggedIn = true;
this._router.navigate(['/order']);
}
else
//replace this with a page
alert("Sign in with a correct name!");
}
}
I am able to display the user's details when they signUp but when a user logs in, I cannot get the response which is meant to be a JSON object like this:
{
"address": {
"addition": null,
"city": "Nijmegen",
"housenumber": "908",
"street": "de Voorstenkamp"
},
"email": "ernestina_a#ive.com",
"password": "678",
"username": "feedme"
}
I tried to create two classes, User.ts
import {Address} from "./Address.ts";
export class User {
username:string;
email:string;
password:string;
address:Address;
constructor(username:string, email:string, password:string,address:Address){
this.username = username;
this.email = email;
this.password = password;
this.address = address;
}
public static createEmptyUser():User{
return new User("","","",null);
}
}
And address.ts
export class Address {
street:string;
housenumber:string;
addition:string;
city:string;
constructor(street:string, housenumber:string,addition:string,city:string) {
this.street = street;
this.housenumber = housenumber;
this.addition = addition;
this.city = city;
}
public static createEmptyAddress():Address {
return new Address("","","","");
}
}
Using this two classes, I tried to parse the response to get a user object but I am not able to get any response at all.
Can anyone here help me out ? I will really appreciate it.
Hi I am just showing an example how to get the body part from any http response:
getMemberList(){
this.teamService.getMemberList().subscribe(
(res)=>{
console.log("getMemberList: ",res.json());
},
(err)=>{
console.log(err);
}
)
}
In the above code I have called an HTTP POST request in teamService.ts . So after coming response from any API you will have to do res.json to get the body part from response.

Can I pass an object from Angular2 to an MVC5 Post?

I am trying to pass my object from Angular2 through a post to an MVC Controller. I was hoping I could pass the actual object in, but all of my properties are appearing as null when it gets into my controller. Is it possible to pass the entire object in? I also tried with "UrlSearchParameters" but it didnt work either.
Here's my controller post function:
[HttpPost]
public JsonResult AddClient(Models.Client client)
{
var cli = new Models.Client();
cli.name = client.name;
cli.npi = client.npi;
cli.dateAdded = DateTime.Now.ToShortDateString();
return Json(cli);
}
Here's my client type:
export interface Client {
name: string;
npi: number;
dateAdded?: string;
id?: number
}
Here's my Angular2 service:
import {Injectable} from 'angular2/core';
import {Client} from './client';
import {RequestOptions, Http, Response, Headers, URLSearchParams} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
#Injectable()
export class ClientService {
constructor(private http: Http) { }
getClients(): Observable<Client[]> {
return this.http.get('/Client/GetClients')
.map(this.extractData);
}
addClient(client: Client): Observable<Client> {
let clientUrl = '/Client/AddClient';
let body = JSON.stringify({ client });
let header = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: header });
return this.http.post(clientUrl, body, options)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
if (res.status < 200 || res.status >= 300) {
throw new Error('Bad response status: ' + res.status);
}
let body = res.json();
return body || {};
}
private handleError(error: any) {
// In a real world app, we might send the error to remote logging infrastructure
let errMsg = error.message || 'Server error';
console.error(errMsg); // log to console instead
return Observable.throw(errMsg);
}
}
Thanks for any help!
You try the following:
addClient(client: Client): Observable<Client> {
let clientUrl = '/Client/AddClient';
let body = JSON.stringify(client); // <----------
instead of
addClient(client: Client): Observable<Client> {
let clientUrl = '/Client/AddClient';
let body = JSON.stringify({ client });
In your case, I think that you receive the following content:
{
"client": {
// client properties
"name": "some name",
"npi": "some npi",
(...)
}
}
instead of
{
// client properties
"name": "some name",
"npi": "some npi",
(...)
}

DART : how can assign the result of httpRequest on a property object?

I would like to save in a Object property (my_json) a JSON List loaded from an external file.
With this code my_json properties is always equal to null :{
Thanks in advance for your help :)
#CustomTag('scaffold-toolsbar-element')
class MyCustomTag extends PolymerElement{
void click_menu_item(String label) {
shadowRoot.querySelector('#page_name').text = label;
}
MyCustomTag.created() : super.created(){
var menu_list = new MenuList('menu_items.json');
addElementToMenu(list_value){
var newElement = new Element.tag('core-item');
newElement.setAttribute("icon", list_value["icon"]);
newElement.setAttribute("label", list_value["label"]);
newElement.onClick.listen((e) => click_menu_item(list_value["label"]));
shadowRoot.querySelector('#core_menu_item').children.add(newElement);
};
menu_list.my_json.forEach(addElementToMenu);
}
}
class MenuList {
String path;
List my_json;
MenuList(String path) {
this.path = path;
var httpRequest = new HttpRequest();
httpRequest
..open('GET', path)
..onLoadEnd.listen((e) => requestComplete(httpRequest))
..send('');
}
requestComplete(HttpRequest request) {
// request.status is 200
// request.responseText is
// "[ {"icon": "settings", "label": "Signin", "main_page": "signin-element"}, {"icon": "home", "label": "About", "main_page": "about-page-element"} ]"
if (request.status == 200) {
this.my_json = JSON.decode(request.responseText);
}else{
this.my_json = null;
}
}
}
Your MenuList class could look like
class MenuList {
String path;
List my_json;
static Future<MenuList> create(String path) {
return new MenuList()._load(path);
}
Future<MenuList>_load(String path) {
Completer completer = new Completer();
this.path = path;
var httpRequest = new HttpRequest();
httpRequest
..open('GET', path)
..onLoadEnd.listen((e) {
requestComplete(httpRequest);
completer.complete(this);
})
..send('');
return completer.future;
}
requestComplete(HttpRequest request) {
if (request.status == 200) {
this.my_json = JSON.decode(request.responseText);
}else{
this.my_json = null;
}
}
}
and the constructor of MyCustomTag like
void attached() {
super.attached();
var menu_list;
MenuList.create('menu_items.json')
.then((ml) {
menu_list = ml;
addElementToMenu(list_value){
var newElement = new Element.tag('core-item');
newElement.setAttribute("icon", list_value["icon"]);
newElement.setAttribute("label", list_value["label"]);
newElement.onClick.listen((e) => click_menu_item(list_value["label"]));
shadowRoot.querySelector('#core_menu_item').children.add(newElement);
};
menu_list.my_json.forEach(addElementToMenu);
});
}
I haven't actually tested this code but at leas the analyzer was satisfied.
This is the code you require:
HttpRequest.request(path, responseType: 'json').then((HttpRequest request) {
var json = request.response;
});
Note that there is a bug in Dartium at the moment:
https://code.google.com/p/dart/issues/detail?id=20129
As a workaround you can omit the responseType parameter and use request.responseText.
Regards, Robert
The solution come from Robert. I try to read an Object property before the JSON List result is assigned to. So I have always a null property...
To avoid that, I add an optional parameter async to my HttpRequest.open like that: ..open('GET', path, async:false)
This is the final code.
#CustomTag('scaffold-toolsbar-element')
class MyCustomTag extends PolymerElement{
void click_menu_item(String label) {
shadowRoot.querySelector('#page_name').text = label;
}
MyCustomTag.created() : super.created(){
var menu_list = new MenuList('menu_items.json');
addElementToMenu(list_value){
var newElement = new Element.tag('core-item');
newElement.setAttribute("icon", list_value["icon"]);
newElement.setAttribute("label", list_value["label"]);
newElement.onClick.listen((e) => click_menu_item(list_value["label"]));
shadowRoot.querySelector('#core_menu_item').children.add(newElement);
};
menu_list.my_json.forEach(addElementToMenu);
}
}
class MenuList {
String path;
List my_json;
MenuList(String path) {
this.path = path;
var httpRequest = new HttpRequest();
httpRequest
..open('GET', path, async:false)
..onLoadEnd.listen((e) => requestComplete(httpRequest))
..send('');
}
requestComplete(HttpRequest request) {
if (request.status == 200) {
this.my_json = JSON.decode(request.responseText);
}else{
this.my_json = null;
}
}
}

dart append data to html on future .then()

So i have this code:
import 'dart:html';
import 'dart:json';
class BaseModel {
Map values;
String _url;
// another basic properties
// constructor defined here
fetch() {
var el = document.query('#container');
HttpRequest.getString(_url).then(
(result) {
values = new Map.from(parse(result));
el.innerHtml = values['name'];
return result;
})
}
}
void main() {
BaseModel bm = new BaseModel(url: /path/to/test.json);
bm.fetch();
}
And i have a json data like this:
{
"name" : "Andrew",
"age" : 20
}
I expect to see "Andrew" on the DOM, but i see nothing. If i change the
el.innerHtml = "SOME_TEXT"
then i can see the "SOME_TEXT" text displayed.
Can you guys help me?
What do you see in the JavaScript console if you print the name?
What happens if you add an error handler?
Something along the following lines:
HttpRequest.getString(_url)
.then((result) {
values = new Map.from(parse(result));
print(values['name']);
el.innerHtml = values['name'];
return result;
})
.catchError((e) => print(e));

Resources