Trying get JSON array from json-server using observables and then giving the value to frontend and perform search on the JSON array received through observable
created a service and used HTTP get to connect to server and subscribed to it
created for loop to get value from returned value of subscription
**service.ts**
export class FormdtService {
baseul='http://localhost:3000/objects'//jsonserver url
constructor(private http:HttpClient) { }
getdt():Observable<any>{
return this.http.get(this.baseul)
}
}
**component.ts**
export class FormsComponent implements OnInit {
constructor(public fbu:FormBuilder,private fdts:FormdtService) {}
//creates the reactive form
form=this.fbu.group({
un:'',
id:''
})
// baseul='http://localhost:3000/objects/';
//ngsubmit control of form brings this function
ser(){
this.fdts.getdt().subscribe(dt=>{
console.log("data: "+dt[0])
this.formdt.push(dt)
//console.log("formdt :"+this.formdt[0])
for (let ite in this.formdt){
let ite1=JSON.parse(ite)
// console.log("ite :"+this.formdt[ite]);
//console.log("ite1"+ite1);
this.idlist.push(ite1.person.bioguideid.value)
if(ite1.person.bioguideid.stringify==this.idsearch)
this.objson=ite1
}});
}
idsearch:string
formdt:string[]
idlist:string[]
objson:JSON
ngOnInit() {
}
//this function is attached to button in frontend
ser(){
this.fdts.getdt().subscribe(dt=>
this.formdt.push(dt)//subscribes to service
for (let ite in this.formdt){
let ite1=JSON.parse(ite)
this.idlist.push(ite1.person.bioguideid.value)
if(ite1.person.bioguideid.value==this.idsearch)
this.objson=ite1
})}
**json**
[
{
"caucus": null,
"congress_numbers": [
114,
115,
116
],
"current": true,
"description": "Senior Senator for Tennessee",
"district": null,
"enddate": "2021-01-03",
"extra": {
"address": "455 Dirksen Senate Office Building Washington DC 20510",
"contact_form": "http://www.alexander.senate.gov/public/index.cfm?p=Email",
"fax": "202-228-3398",
"office": "455 Dirksen Senate Office Building",
"rss_url": "http://www.alexander.senate.gov/public/?a=rss.feed"
},
"leadership_title": null,
"party": "Republican",
"person": {
"bioguideid": "A000360",
"birthday": "1940-07-03",
"cspanid": 5,
"firstname": "Lamar",
"gender": "male",
"gender_label": "Male",
"lastname": "Alexander",
"link": "https://www.govtrack.us/congress/members/lamar_alexander/300002",
"middlename": "",
"name": "Sen. Lamar Alexander [R-TN]",
"namemod": "",
"nickname": "",
"osid": "N00009888",
"pvsid": "15691",
"sortname": "Alexander, Lamar (Sen.) [R-TN]",
"twitterid": "SenAlexander",
"youtubeid": "lamaralexander"
},
"phone": "202-224-4944",
"role_type": "senator",
"role_type_label": "Senator",
"senator_class": "class2",
"senator_class_label": "Class 2",
"senator_rank": "senior",
"senator_rank_label": "Senior",
"startdate": "2015-01-06",
"state": "TN",
"title": "Sen.",
"title_long": "Senator",
"website": "https://www.alexander.senate.gov/public"
},//end of single json array object
{
"caucus": null,
"congress_numbers": [
114,
115,
116
],
"current": true,
"description": "Senior Senator for Maine",
"district": null,....same repetition of structure
The ser function should give whole JSON array present in server to formdt[] and then iterate over it and get every object and convert to JSON and push bioguide to id array,search id from input and match with JSON nested value of each object in the array
nothing happens gives error in console :
_this.formdt is undefined at line 37 (this.fdts.getdt().subscribe(dt=>this.formdt.push=dt))
Given error is pretty explicit : this.formdt is undefined.
You've declared preperty type but haven't initialize it.
So replace formdt:string[] with formdt:string[] = []
Related
This feels like a really stupid question, but my lack of JS knowledge combined with lack of AWS knowledge has me in a tight spot! I'm just trying to get to grips with a basic AWS stack i.e. Lambda/Dynamo/API Gateway for some basic API work.
If I want a simple API endpoint to handle PUT requests e.g. https://my.endpoint.amazonaws.com/users. If I have a DynamoDB table with a composite primary key of userID and timestamp I could use the code snippet below to take the unknown data (attributes that weren't known when setting a schema), but this obviously doesn't work well
const dynamo = new AWS.DynamoDB.DocumentClient();
let requestJSON = JSON.parse(event.body);
await dynamo
.put({
TableName: "myDynamoTable",
Item: {
userID: requestJSON.userID,
timestamp: requestJSON.timestamp,
data: requestJSON.data
}
})
.promise();
I could send a PUT request with the following JSON
{
"userID": "aaaa1111",
"timestamp": 1649677057,
"data": {
"address": "Elm Street",
"name": "Glen"
}
}
but then address and name get shoved into a single DynamoDB attribute named data. How do I construct the node code to create a new attribute named address and one named name with the corresponding values, if I didn't know these attributes i.e. I want to use JSON in my request like below, but assuming I don't know this and can't use requestJSON.address
{
"userID": "aaaa1111",
"timestamp": 1649677057,
"address": "Elm Street",
"name": "Glen"
}
You can use the spread operator, for example:
const data = {
address: "Elm Street",
name: "Glen",
};
const item = {
userID: "aaaa1111",
timestamp: 1649677057,
...data,
};
console.log("item:", item);
If you insist on the API contract as
{
"userID": "aaaa1111",
"timestamp": 1649677057,
"data": {
"address": "Elm Street",
"name": "Glen"
}
}
then you can do mapping on the TypeScript level
const request: {userID: string, timestamp: number, data: any} = {
"userID": "aaaa1111",
"timestamp": 1649677057,
"data": {
"address": "Elm Street",
"name": "Glen"
}
};
const ddbObject: any = {
"userID": request.userID,
"timestamp": request.timestamp
};
Object
.keys(request.data)
.forEach(key => ddbObject[key] = request.data[key]);
Representation of ddbObject is
{
"userID": "aaaa1111",
"timestamp": 1649677057,
"address": "Elm Street",
"name": "Glen"
}
How would access the _id and state values?
Here's the data
{
"data": {
"totalSamplesTested": "578841",
"totalConfirmedCases": 61307,
"totalActiveCases": 3627,
"discharged": 56557,
"death": 1123,
"states": [
{
"state": "Lagos",
"_id": "O3F8Nr2qg",
"confirmedCases": 20555,
"casesOnAdmission": 934,
"discharged": 19414,
"death": 207
},
{
"state": "FCT",
"_id": "QFlGp4md3y",
"confirmedCases": 5910,
"casesOnAdmission": 542,
"discharged": 5289,
"death": 79
}
]
}
}
What you have shown is a string in JSON format. You can convert that to a JavaScript object and then start to get the values you need from it.
let str = ‘{
"data": {
"totalSamplesTested": "578841",
"totalConfirmedCases": 61307,
"totalActiveCases": 3627,
"discharged": 56557,
"death": 1123,
"states": [
{
"state": "Lagos",
"_id": "O3F8Nr2qg",
"confirmedCases": 20555,
"casesOnAdmission": 934,
"discharged": 19414,
"death": 207
},
{
"state": "FCT",
"_id": "QFlGp4md3y",
"confirmedCases": 5910,
"casesOnAdmission": 542,
"discharged": 5289,
"death": 79
}
]
}
} ‘;
(Note, I have put the string in single quotes so it can be shown properly here but in your code you need to put it in back ticks so it can span many lines)
Now convert it to a JavaScript object.
let obj = JSON.parse(str);
Now look closely at the string to see how the object is structured. It actually has just one item in it, data. And that is itself an object with several items, one of which is states which is an array.
So, obj.data.states[0] is the array’s first entry. That is an object and has _id and state items.
You can step through the array extracting the ._id and .state entries.
I have an object like:
export const contact = {
_id: "1",
first:"John",
name: {
first:"John",
last:"Doe"
},
phone:"555",
email:"john#gmail.com"
};
I am reading it like
return (
<div>
<h1>List of Contact</h1>
<h1>{this.props.contact._id}</h1>
</div>
)
in this scenario I am getting expected output.
return (
<div>
<h1>List of Contact</h1>
<h1>{this.props.contact.name.first}</h1>
</div>
)
But when I read the nested property I am getting error like
Uncaught TypeError: Cannot read property 'first' of undefined
How to read these king of nested objects in react? Here is my source
Three things you need to address here:
this is your contacts-data and i don't see any first property within the name object:
export const contacts = {
"name": "mkyong",
"age": 30,
"address": {
"streetAddress": "88 8nd Street",
"city": "New York"
},
"phoneNumber": [{
"type": "home",
"number": "111 111-1111"
}, {
"type": "fax",
"number": "222 222-2222"
}]
};
You are calling this.props.fetchContacts(); on componentDidMount, hence in the first render call the state is still empty, the action call and the reducer will pass new props or change the state then you get to the second render call and that's the moment you have the data ready for use.
So you should check for the existing of the data before you try to use it. one way is to just conditionally render it (of course there are better ways to do it, this is just to make a point):
render() {
const { contacts } = this.props;
return (
<div>
<h1>List of Contacts</h1>
<h2>{contacts && contacts.name && contacts.name.first
//still getting error. "this.props.contacts.name" alone works
}</h2>
<h2>{contacts && contacts.address && contacts.address.city}</h2>
</div>
)
}
You are trying to use this.props.contact.name.first is that a typo? shouldnt it be contacts instead of contact?
EDIT:
As a followup for your comment, as a general rule in JavaScript (or any other language for that manner) you should always check the existence reference of an object before you are trying to access it's properties.
As for your use case you can use defaultProps if you must have a value to render or you can even simplify the scheme of your data.
This is much simpler to manage:
export const contacts =
{
"fName": "mkyong",
"lName": "lasty",
"age": 30,
"streetAddress": "88 8nd Street",
"city": "New York",
"homeNumber": "111 111-1111",
"faxNumber": "222 222-2222"
};
Than this:
export const contacts =
{"name": "mkyong",
"age": 30,
"address": {
"streetAddress": "88 8nd Street",
"city": "New York"
},
"phoneNumber": [
{
"type": "home",
"number": "111 111-1111"
},
{
"type": "fax",
"number": "222 222-2222"
}
]
};
Edit
I tried to access value in object using the incorrect way, I have edited this question to stop others from making the same mistake.
Simply store that object into a variable (something like var obj = {...} and type obj.skills to get the skills array back. If you wanted to get test from the cal_strs array, you can do obj.cal_strs[0].test
<pre>
var obj =
{
"skills": [],
"languages": [],
"cal_strs": [{
"test": null,
"primary_test": null
}],
"id": 123,
"my_id": 1346,
"username": "blahblah",
"full_name": "mr blah",
"email": "blah#blah.com",
"location": "boston",
"manager": "boss",
"status": 1,
"abc_status": "here",
"s_s": "2010-06-08T23:00:00Z",
"s_e": "2010-06-13T07:00:00Z",
"n_c": "2010-07-08T07:00:00Z",
"last_here": null
}
console.log(obj.location);
console.log(obj.status);
<pre>
what you have here is a object literal, witch can be manipulated without the use of jquery, to read this object you use the dot notation to get the object value based on the key
obj.key = value
var obj =
{
"skills": [],
"languages": [],
"cal_strs": [{
"test": null,
"primary_test": null
}],
"id": 123,
"my_id": 1346,
"username": "blahblah",
"full_name": "mr blah",
"email": "blah#blah.com",
"location": "boston",
"manager": "boss",
"status": 1,
"abc_status": "here",
"s_s": "2010-06-08T23:00:00Z",
"s_e": "2010-06-13T07:00:00Z",
"n_c": "2010-07-08T07:00:00Z",
"last_here": null
}
console.log(obj.location);
console.log(obj.status);
var abc_status = obj.abc_status;//save the value to a variable
You're trying to access your json object as if it's an array. It's not. You can access your objects already since it's already a proper javascript object (it's not json). Simply store that object into a variable (something like var obj = {...} and type obj.skills to get the skills array back. If you wanted to get test from the cal_strs array, you can do obj.cal_strs[0].test.
Use underscore(_.pluck) get the specific values from the object.
Or try to define a new variable and reassign it .
var s = {
"skills": [],
"languages": [],
"cal_strs": [{
"test": null,
"primary_test": null
}],
"id": 123,
"my_id": 1346,
"username": "blahblah",
"full_name": "mr blah",
"email": "blah#blah.com",
"location": "boston",
"manager": "boss",
"status": 1,
"abc_status": "here",
"s_s": "2010-06-08T23:00:00Z",
"s_e": "2010-06-13T07:00:00Z",
"n_c": "2010-07-08T07:00:00Z",
"last_here": null,
}
var t = {};
t['location'] = s.location;
t['status'] = s.status;
t['abc_status'] = s.abc_status;
t['s_s'] = s.s_s;
t['s_e'] = s.s_e;
t['n_c'] = s.n_c;
in case multiple arrays use underscore.
I'm having some problems when trying to retrieve values from a JSON response sent via the $.post() method in jQuery. Here is the script:
var clickedName = $('#customerId').val();
$.post("/customer-search", { name: clickedName }).done( function(response) {
var results = $.parseJSON(response);
console.log(results);
$('#account-name').html(results.firstname + ' ' + results.lastname);
$('#email').html(results.email);
$('#telephone').html(results.telephone);
if (results.fax) {
$('#fax').html(results.fax);
} else {
$('#fax').html('n/a');
}
$('#personal').fadeIn();
return false;
});
Just to explain, I'm using twitter typeahead in a Symfony2 project, and basically this script will fire when a name is clicked (selected) from the list after typing. The customer-search URL runs a search of the database as follows:
$q = $request->request->get('name');
$em = $this->getDoctrine()->getManager();
$customer = $em->getRepository('AppBundle:Oc73Customer')->findLikeName($q);
$addresses = $em->getRepository('AppBundle:Oc73Address')->findByCustomerId($customer[0]['customerId']);
$results = array();
$results['customer'] = $customer;
$results['addresses'] = $addresses;
return new Response(json_encode($results));
Which will successfully return a Json encoded response, and the value of 'response' which is printed in the console (as per the jquery above) is:
{
"customer": [{
"firstname": "Mike",
"lastname": "Emerson",
"email": "xxxx#xxxx.co.uk",
"telephone": "01234 5678910",
"fax": null,
"password": "8e1f951c310af4c20e2cd6b68dee506ac685d7ae",
"salt": "e2b9e6ced",
"cart": null,
"wishlist": null,
"newsletter": 0,
"addressId": 84,
"customerGroupId": 1,
"ip": null,
"status": 1,
"approved": 1,
"token": null,
"dateAdded": {
"date": "2016-02-16 12:59:28.000000",
"timezone_type": 3,
"timezone": "Europe/Berlin"
},
"availCredit": null,
"customerId": 75
}],
"addresses": [{}]
}
I am trying to retrieve the customer details by using the method I always use, so to get the firstname, I use results.firstname where results is a parsed JSON string, as written in my jQuery response.
However, all I get from results.firstname is undefined, even when it clearly is defined. So, basically, I'm wondering what I am doing wrong?
Hope someone can shed some light on my problem.
The properties you're trying to access are objects in the customer array, not on the parent object itself. Assuming that the response only ever contains one customer object then you can use result.customer[0], like this:
$.post("/customer-search", { name: clickedName }).done(function(response) {
var results = $.parseJSON(response);
var customer = response.customer[0];
$('#account-name').html(customer.firstname + ' ' + customer.lastname);
$('#email').html(customer.email);
$('#telephone').html(customer.telephone);
$('#fax').html(customer.fax ? customer.fax : 'n/a');
$('#personal').fadeIn();
});
If it's possible that multiple customer objects will be returned in the array the you would need to amend your code to loop through those objects and build the HTML to display them all - without using id attributes.
I was able to access it like "results.customer[0].firstname"
var cus =
{
"customer": [{
"firstname": "Mike",
"lastname": "Emerson",
"email": "xxxx#xxxx.co.uk",
"telephone": "01234 5678910",
"fax": null,
"password": "8e1f951c310af4c20e2cd6b68dee506ac685d7ae",
"salt": "e2b9e6ced",
"cart": null,
"wishlist": null,
"newsletter": 0,
"addressId": 84,
"customerGroupId": 1,
"ip": null,
"status": 1,
"approved": 1,
"token": null,
"dateAdded": {
"date": "2016-02-16 12:59:28.000000",
"timezone_type": 3,
"timezone": "Europe/Berlin"
},
"availCredit": null,
"customerId": 75
}],
"addresses": [{}]
}
alert(cus.customer[0].firstname);