read JSON using angular2 - json

I have problem with json\object I'M trying to pull the data out from it and I failed.
I have this API that I pull my data from:
http://api.fixer.io/latest?base=CAD
I have placed it on variable results,
If i want to get to object paramater date,base,rate like below:
calc(details) {
let results = [this.networkServices.getCurrency(details)]; // object is here "getCurrency deal with the GET request.
alert(results.base);
}
I get the error code:
[02:58:36] transpile update started ...
[02:58:38] typescript: D:/ionic/firstApp/src/pages/currency/currency.ts, line: 19
Property 'base' does not exist on type 'Promise<any>[]'.
L18: let results = [this.networkServices.getCurrency(details)];
L19: alert(results.base);
[02:58:38] transpile update failed
Its feel weird that I can't pull the data out, what could it be?
get currency function
getCurrency(obj){
console.log("function fired!")
let url = `http://api.fixer.io/latest?base=${obj.selectedCurrency}`;
return this.http.get(url).toPromise().then(res => res.json());
}

Try updating your getCurrency() to just return the promise by removing the then():
getCurrency(obj){
console.log("function fired!")
let url = `http://api.fixer.io/latest?base=${obj.selectedCurrency}`;
return this.http.get(url).toPromise();
}
Then the solution from #pe8ter should work:
this.networkServices.getCurrency(details).then(result => alert(result))

The service request is asynchronous so the result of the request is a Promise that resolves to an object, not the object itself. Try something like this:
this.networkServices.getCurrency(details).then(result => alert(result))

Related

Angular 2 get json data and define it as new array in component

I got my json file and I am getting it on the service. Then I am trying to subscribe to it in the component, but in console.log(this.jsonObj) I get empty array. Also if I write console.log(data) - I get json data.
Service :
objUrl = 'assets/jsons/obs.json';
constructor(private http: HttpClient) {
console.log('Hello ObjectsProvider Provider');
}
getObjectsJson() {
return this.http.get(this.objUrl);
}
Component :
jsonObj = {};
this.object.getObjectsJson().subscribe((data =>
this.jsonObj = data
))
console.log(this.jsonObj)
Issue
You are trying to get the Asynchronous data in Synchronous fashion. You are logging the data console.log(this.jsonObj) outside of Observable. So it will get executed without waiting for the result to come from API.
Fix
Just move the log or any code you want to execute the after API inside subscribe. So you your code will look like
jsonObj = [];
this.object.getObjectsJson().subscribe((data =>
this.jsonObj = data;
console.log(this.jsonObj); //<-- data will be appear here.
))
The service method is asynchronous, so the code inside the subscribe() (which makes the assignment) executes at some time in the future, when the http call returns. Your log statement is outside of the subscription, so it happens before the assignment. Try putting the log statement inside the subscription, right after the assignment.
console.log(this.jsonObj) will run before the response of the server. You can work with it as it is. It will run perfectly. you can test it like this
<p *ngIf="jsonObj !== undefined">{{jsonObj.field}}</p>
if you want to check it with console.log, just add it in the subscription like this
this.http.getObjectsJson().subscribe((data => {
this.jsonObj = data
console.log(this.jsonObj)
}));"

React.js: setState method setting variable to a string instead of object... is there a workaround?

I am trying to fetch a simple JSON element from express.js. I am trying have React assign it to a state variable on the front end. I am using this code to do so:
componentDidMount() {
fetch("/user")
.then(response => response.json())
.then(result => this.setState({myUser:result}))
}
But when I run typeof myUser after this setState command, it says string instead of object. I've tried using JSON.parse(), etc. But either I get an error or it continues to assign the data as a string rather than JSON. What sort of syntax do I need to use in this fetch-then context to coerce the data assignment to be JSON?
I have read this link:
With this code:
componentDidMount(){
fetch('https://abx.com/data/tool.json').then(response =>{
if (!response.ok) throw Error('Response not ok')
return response.json(); // This is built in JSON.parse wrapped as a Promise
}).then(json => {
this.setState({"sections" : json});
}).catch(err =>{
console.log(err);
});
}
But it doesn't solve the problem. I ran this code directly in my application verbatim. When I run typeof on the variable, it says string instead of object. I looked at other posts on Stack Overflow, but I did not see a solution to this.
I figured out what was going wrong (after many hours of experimenting):
On the server side, I was creating a "homegrown" JSON object using string and variable concatenation. I also tried creating the JSON object by doing this:
var str = "name:" + name + ", department:" + department
var user = {str};
Both of these were not working in subtle ways... despite trying different types of gadgetry on the client side, I couldn't get React to interpret the data as a JSON object. But then I had an idea to construct the JSON on the server side (in Express.js) like this:
var user = {};
user["name"] = name;
user["department"] = department;
That immediately cleared things up on the server side and the client side. When using setState() in React, it now sets the value as an object (which was the goal all along).
I think this can be useful to others... if React doesn't seem to understand the JSON, perhaps it is being sent from the server in a subtly incorrect format.

Unable to access data inside a string (i.e. [ object Object ]) that was originally sent as a JSON object

I'm using axios to send a JSON object as a parameter to my api. Before it post request is fired, my data starts of as a JSON object. On the server side, when I console.log(req.params) the data is returned as such
[object Object]
When I used typeof, it returned a string. So then I went to use JSON.parse(). However, when I used that, it returned an error as such
SyntaxError: Unexpected token o in JSON at position 1
I looked for solutions, but nothing I tried seemed to work. Now I'm thinking I'm sending the data to the server incorrectly.
Here's my post request using axios:
createMedia: async function(mediaData) {
console.log("SAVING MEDIA OBJECT");
console.log(typeof mediaData)
let json = await axios.post(`http://localhost:3001/api/media/new/${mediaData}`)
return json;
}
Any thoughts on how I can solve this?
You need to update your code using axios to provide the mediaData in the body of the request instead of the URL:
createMedia: async function(mediaData) {
console.log("SAVING MEDIA OBJECT");
console.log(typeof mediaData)
let json = await axios.post(`http://localhost:3001/api/media/new/`, mediaData)
return json;
}
In the backend (assuming you're using express here), you need to configure your application to use bodyParser:
var express = require('express')
, app = express.createServer();
app.use(express.bodyParser());
And then in your controller update your console.log(req.params) to console.log(req.body); then restart your node server

Multicast observable: attempting to subscribe results in "cannot read property 'subscribe' of undefined" error

I have a need in my code to perform an AJAX request and send the resulting data to two different places, so I figured using a multicast observable was the easiest way of achieving this. My code looks like this:
In the constructor for my 'app' object:
this.getEpisodeDescription = (id) => jsonLoader("http://www.randomtext.me/api/lorem/p-2/8-24", "text_out");
function jsonLoader (url, field)
{
let stream = Rx.Observable.ajax ({ url: url, crossDomain: true })
.retry (1)
.pluck ("response");
if (field !== undefined)
return stream.pluck(field);
else
return stream;
}
I've successfully used this method before to retrieve data for a single receiver, so I'm sure this is working OK. The caller is new, however:
loadSummary (id)
{
let cachedValue = this.summaries.get(id);
if (cachedValue !== undefined) return Rx.Observable.of(cachedValue);
let observable = this.app.getEpisodeDescription(id);
let multicast = observable.multicast ().refCount ();
multicast.subscribe(result => this.summaries.put(id, result));
return multicast;
}
When I try executing this method, I get the following stack trace:
Uncaught TypeError: Cannot read property 'subscribe' of undefined
at Observable.ConnectableObservable._subscribe (app.js:44193)
at Observable._trySubscribe (app.js:10253)
at Observable.subscribe (app.js:10241)
at RefCountOperator.call (app.js:44275)
at Observable.subscribe (app.js:10238)
at AsyncAction.SubscribeOnObservable.dispatch (app.js:71532)
at AsyncAction._execute (app.js:21083)
at AsyncAction.execute (app.js:21058)
at AsyncScheduler.flush (app.js:21156)
(Ignore file name and line numbers -- I'm using webpack and it doesn't seem to be producing a working line number map at the moment)
Any ideas what's going on? Specifically, how does it happen that I get an object out of the call to multicast that has appropriate subscribe etc methods, but when you try to subscribe to it it apparently can't subscribe to the parent?
The first parameter to the multicast() operator is either Subject factory function or a Subject instance.
This means you should be using it like this if you want to have one shared Subject instance:
let multicast = observable.multicast(new Subject()).refCount();
... or like this to make a new Subject for every observer:
let multicast = observable.multicast(() => new Subject()).refCount();

Get real response of ngResource save()

I have the following situation:
I use ngResource to save some data to the mysql database and after the successfull save() I want to log the json response the server sends to me:
Document.save({}, postData, function(response){
console.log(response);
});
This does not result in a simple response, but in something like an object with its own methods. I want some smple output like the response.data after an $http.$get:
{
"docClass":"testets",
"colCount":1,
"columns":null,
"groupid":7,
"id":19,
"lang":"de",
"title":"test",
"version":1409849088,
"workflow":"12234"
}
Greets
Check out this answer
Promise on AngularJS resource save action
So I think in your case you need to do
var document = new Document(postData);
document.$save()
.then(function(res){});
But also from the link I provided
This may very well means that your call to $save would return empty reference. Also then is not available on Resource api before Angular 1.2 as resources are not promise based.