I want the code below to be able to fetch JSON data from a simple API I have set up.
export class FaqFakeDb
{
public static data = fetch('https://#######.co.uk/api/faq/');
}
This is for a FAQ page and its meant to be pulling data from the API. I am new to typescript and Angular so forgive me if I've made a simple mistake.
I want it to function like this:
export class FaqFakeDb
{
public static data = [
{
"id":"1",
"question":"test1",
"answer":"test1"
},
{
"id":"2",
"question":"test1",
"answer":"test1"
},
{
"id":"3",
"question":"test1",
"answer":"test1"
}
];
}
Any help will me much appretiated :)
fetch returns a promise, so data will be a promise. Any time you want to access data you will have to use async/await or .then or something else to handle promises. You also don't have any error handling in case your API call fails.
One example of how you could handle this would be:
async ngOnInit() {
try {
const response = await FaqFakeDb.data;
this.quesitons = await response.json();
} catch {
// fetch encountered an error; you can handle it here.
}
}
However, I would recommend that you use Angular's built in HttpClientModule instead and make the API call as it's needed (in the component that needs it) rather than when an arbitrary class is declared.
Related
I have a JSON object in my assets folder I am reading as below
data.json
[
{
"modName":"deployment",
"year":"1992",
"description":"basic deployment"
},
{
"modName":"Integration",
"year":"1995",
"description":"popular integration"
}
]
In my dataService.ts file my reading JSON object
getData(){
return this.http.get('assests/data.json');
}
getDataInfo{
return this.getData().subscribe(data=>{
if(data!==undefined)
for(let i in data){
if(data[i].modName=='deployment'){
return data[i];
}
}
})
}
I am accessing this object in my main component
let data = this.dataService.getDataInfo()
this is giving me a subscriber though I want a specific data object.How can I retrieve it?
getData goes in service, getDataInfo goes in component and then in component you can create variable myDataInfo and just on line where you return data do this
this.myDataInfo = data[i]
OR
same as above with service and component method, but you can store your data to some variable eg. this.myJsonData
and then you can do something like this
get myDataInfo() {
return this.myJsonData.filter((item) => item.modName=='deployment')[0]
}
and the you just can use that object in your template easy.
I have a webapp that gets via Json stuff put it in objects to display them.
I already did it two times with services and classes.
But now i copy and paste the old code make some slight changes to make sure it redirect to the good classes but now i get an array with functions instead an array with objects.
Here is my constructor that calls upon the the service classes and send things to the console
constructor(private featureService : FeatureService, private scenarioservice : ScenarioService, private failuresService : FailuresService){
//hier worden de features en failures opgehaald
this.featureService.getFeatures().subscribe(res => {
this.featureArray = res.getFeatureArray();
console.log(res.getFeatureArray());
});
this.failuresService.getFailures().subscribe(res => {
this.failureArray = res.getFailureArray();
console.log(res.failures[0].method);
console.log(this.failureArray);
});
}
}
Here is failuresService.getFailures:
import { Injectable } from "#angular/core";
import {Http, Response} from "#angular/http";
import {Failure} from "./Failure";
import {Failures} from "./failures";
#Injectable()
export class FailuresService {
constructor(protected http: Http) {}
getFailures() {
return this.http.get('http://localhost:8080/testresultaten')
.map((response: Response) => response.json())
.map(({failures = [Failure]}) => new Failures(failures));// deze error is bullshit
}
}
This is the Json that I get and want to get in an class:
{
"failures:": [
{
"method": "canRollOneGame",
"object": "BowlingGame.GameTest"
},
{
"method": "canCountNighteeneight",
"object": "FizzBuzz.FizzBuzzTest"
}
]
}
Here are the Failure and Failures classes:
import {Failure} from "./Failure";
export class Failures {
constructor(public failures : Failure[]){}
public getFailureArray(): Failure[]{
return this.failures;
}
}
export class Failure{
constructor(public method : String , public object : String ){ }
}
I could be wrong but this doesn't look right:
getFailures() {
return this.http.get('http://localhost:8080/testresultaten')
.map((response: Response) => response.json())
.map(({failures = [Failure]}) => new Failures(failures));// deze error is bullshit
}
That last mapping, I'm not sure what it is supposed to do. I've never seen that syntax (doesn't mean it's wrong). I get that you have an incoming array. But what this syntax does {failures = [Failure]} is what I think your problem is. I don't think that will do what you think.
Try this and see what happens:
.map(failures => { console.log ( failures ); new Failures(failures) } );// deze error is bullshit
If you try that with your old mapping, and then this new one, it'd be interesting to see what that console.log traces out. I think doing it your way, you won't see what you expect.
If that sorts you out, then you can try typing the incoming payload (though I'm not sure it'll work; it should be receiving JSON from the previous mapping).
.map( (failures: Array<Failure>) => { console.log ( failures ); new Failures(failures) } );
So if I read it correctly: Your goal is to create an array of Failure objects with the values coming from a JSON array where each of this has a method you'd like to execute somewhere in the code.
If thats the case then I understand what went wrong. As Tim Consolazion mentioned in the comments you only get the values for the Failure object not the Failure object itself (See custom created method error: "is not a function"). So in order to execute the commands from Failure you have to create for each object in your JSON array a Failure object. Something like this:
return this.http.get('http://localhost:8080/testresultaten')
.map((response: Response) => {
let content = response.json();
let failureList: Failure[] = [];
content.forEach(failure => {
failureList.push(new Failure(failure.method, failure.object))
});
return failureList || {};
}
What I wonder is where you found {failures = [Failure]}? I've never seen this before and I've no idea what this is for.
EDIT: I edited the question so it fits your class Failure. The failure in content.forEach(failure => { in an object from your JSON array. You can access the values of it like it is a normal object. In your case with failure.method and failure.object.
I found my problem in the Json the name was function: but in my code it was function so all that was necessary was to make sure it sends function instead of function:
So I am making a rest call to get this JSON Object:
{
"_id":"57a0811276e75ba815d248b0",
"gName":"demo-layout",
"gType":"Content",
"wsId":"57a036c376e75ba815d248ac",
"desc":"Demo-Layout for rapidpage",
"createdDate":"2016-08-02T11:16:34.223Z",
"__v":0
}
Now I want to add an array to this object ,something like this:
{
"_id":"57a0811276e75ba815d248b0",
"gName":"demo-layout",
"gType":"Content",
"wsId":"57a036c376e75ba815d248ac",
"desc":"Demo-Layout for rapidpage",
"createdDate":"2016-08-02T11:16:34.223Z",
"blocks":[], //should be added at runtime
"__v":0
}
So I tried following:
dbPage:any={};
ngOnInit(){
let pageId:string="57a0811276e75ba815d248b0";
this._pagesService.getPageById(pageId).subscribe((Page)=>{
this.dbPage=rapidPage;
console.log(this.dbPage); //this prints the object as shown above
});
this.dbPage.blocks=[];
this.dbPage.blocks.push(block1);
}
But its not modifying the current object,instead its creating new Object as :
{blocks: Array[]}
any inputs?
That's because you're not assigning it in the subscribe call. Due to the async nature of HTTP requests in JavaScript, the code below the subscribe call will be executed before the callback inside the subscribe call.
You can easily fix this by moving the code inside the callback:
dbPage: any = {};
ngOnInit(){
let pageId: string = "57a0811276e75ba815d248b0";
this._pagesService.getPageById(pageId).subscribe((rapidPage) => {
this.dbPage = rapidPage;
console.log(this.dbPage); //this prints the object as shown above
this.dbPage.blocks = [];
this.dbPage.blocks.push(block1);
});
}
I'm new to Angular2 and somehow it's really hard to me to understand how http works in Angular2. I made a simple component which should display a json response. It doesn't work and I have no idea why. I checked many tutorials and tried it with promises as well as observables. Doesn't work. I just can't get the data of the response.
My code:
private doAction() {
this.doHttpRequest().subscribe(
data => this.content = data
);
this.content = JSON.stringify(this.content);
}
private doHttpRequest() {
return this.http.get('http://jsonplaceholder.typicode.com/posts/1')
.catch(this.handleError);
}
this.content is bind to my template. When I click a button to start doAction() for a second I see "" in the template, after another second [object Object]
What is the problem here?
That's the expected behavior
private doAction() {
// schedule HTTP call to server and subscribe to get notified when data arrives
this.doHttpRequest().subscribe(
// gets called by the observable when the response from the server aarives
data => this.content = data
);
// execute immediately before the call to the server was even sent
this.content = JSON.stringify(this.content);
}
To fix it change it to
private doAction() {
this.doHttpRequest().subscribe(
data => {
//this.content = data;
this.content = data.json());
});
);
}
If you want code to be executed after data arrived, then you need to move it inside the subscribe(...) callback.
Since http requests are asynchron you have to put all your logic depending on the results of the http call in the subscribe() callback like this:
private doAction() {
this.doHttpRequest().subscribe(
data => {
this.content = data;
// any more logic must sit in here
}
);
}
private doHttpRequest() {
return this.http.get('http://jsonplaceholder.typicode.com/posts/1')
.map(res => res.json());
.catch(this.handleError);
}
Http call is returning data since it shows "[object Object]" in template. If you want to see the json data in template you can use the json pipe as below.
{{content | json}}
PS: No need of "this.content = JSON.stringify(this.content);" in your code.
I have a Component that has an injected service, which makes an Ajax call. I can receive the JSON data successfully and can dump it into the console after the promise "THEN" returns.
Here's my component. I can see the dumped data, but how do I set the component properties with that JSON and have it accessible in the template? Also, why can't I use "this.get" in my function below?
import Ember from 'ember';
export default Ember.Component.extend({
attr_types: Ember.inject.service('svc-attrtypes'),
atype_list: [],
actions: {
getATypes: function() {
this.get('attr_types').getTypes().then(function(json){
console.log(json);
this.atype_list = json;
console.log(this.atype_list);
// below returns: TypeError: this.get is not a function
this.get('atype_list').pushObjects(json);
});
}
}
});
In my template I have this:
{{#each atype_list.alltypes as |a|}}
<li>{{a.attr_type}} - {{a.attr_type_desc}}</li>
{{/each}}
If I manually place my JSON into the atype_list it shows perfectly on the template. But if I try to set it after my Ajax returns, nothing shows, except for in the console output.
I appreciate any help. I am sure I a missing something simple. ( or more likely, I'm just going about this all wrong)
This changed with anonymous function passed to then. You have to save this or use es6 arrow function syntax.
import Ember from 'ember';
const { service } = Ember.inject;
export default Ember.Component.extend({
attrTypes: service('svc-attrtypes'),
atypeList: [],
actions: {
// es6 version
getATypes(){
this.get('attrTypes').getTypes().then(array => {
this.set('atypeList', array); //replaces original array
this.get('atypeList').pushObjects(array); // adds array's elements to the end
});
}
// es5 version
getATypes: function () {
var _this = this;
this.get('attrTypes').getTypes().then(function(array){
_this.set('atypeList', array);
}
}
}
});
You wrote that you are new to ember, so I added little more syntax sugar. Also check ember-cli if you don't know about that already.