Access individual JSON array item and use for blog post dynamically - arrays

I'm building a simple Nuxt JS blog with a blog.json file containing an array of blog posts which contains:
Title (String)
Body (HTML markup)
Creation (Date)
I will attach the format of this shortly. I know how to iterate over each array item and display it on the page, and I also have a basic understanding and some basic experience with dynamic routing in Nuxt JS.
The problem I'm currently facing is I need to be able to access individual array items and use them as blog posts, e.g: pages/blog/_slug where _slug would be the title of a blog post, with hyphens + all lowercase automatically.
I'm wondering how I would access for instance the Winter blog post in my example and be able to go to mysite.com/blog/winter-blog-post using the following JSON format:
{
"blogs": [
{
"title": "Summer blog post",
"body": "<div class=\"post\">My blog content</div>",
"created": "2019-03-14 10:08:00"
}
{
"title": "Winter blog post",
"body": "<div class=\"post\">My blog content</div>",
"created": "2019-03-15 10:08:00"
},
{
"title": "Spring blog post",
"body": "<div class=\"post\">My blog content</div>",
"created": "2019-03-16 10:08:00"
}
]
}
I essentially want to be able to go to mysite.com/blog/winter-blog-post and have it use the content from that particular array item.

I'll assume you have your pages set up correctly and you can reach /blog/_slug, so it really is just a matter of passing the required params and converting them as needed. In blog.vue you would have a list of your posts and a click on something would navigate to the full article. That click event would trigger a method where you can manipulate the title and use it as a param. So if you have a 'Read More...' button you would assign #click="readMore(blog.title)" to that button.
Then in your methods you take the passed 'title' parameter, change it as you want, and trigger the route change.
methods: {
readeMore(title) {
let passedTitle = title.toLowerCase()
passedTitle = passedTitle.replace(" ", "-")
this.$router.push('/blog/' + passedTitle)
}
}
Then in your _slug.vue you take the passed param, change it back and use that to find your article.
export default {
asyncData({params, $axios }) {
let title = params.passedTitle.replace("-", " ")
let oldTitle = title.charAt(0).toUpperCase() + title.slice(1)
// make your query however you do, if with axios...
$axios.get('/posts', {
params: {
title: oldTitle
}
})
//or if its a vuex state item...
//let post = this.$store.state.posts.find((p) => p.title === oldTitle)
return post
},
}

Related

How to iterate through a JSON array and display specific information based on an API response value in React?

I'm building a ReactJS web application, I have a JSON array:
[{
"2149166938": {
"name": "Classical-42",
"icon": "/common/destiny2_content/icons/e6885dab15cafeaf0dbf80f1ff9b5eb8.jpg"
},
"2149166939": {
"name": "Countess SA/2",
"icon": "/common/destiny2_content/icons/de8906743db9fce201b33802c8498943.jpg"
},
"2154059444": {
"name": "The Long Goodbye",
"icon": "/common/destiny2_content/icons/fe07633a2ee87f0c00d5b0c0f3838a7d.jpg"
}
}]
When I make a call to an API I am returned a value of lets say 2154059444 which is the same value as the last object in my JSON file.
How would I iterate through the JSON file to find the object which has a value of 2154059444 and then access and render it's child values like name or icon?
you can do something like this. Your array is not proper please edit.
Create filtered data :
//here i am addding single dummy point you can make your function
l
et filteredData = [].concat(data.map(test => {
if(Object.keys(test)[0]==="2154059444"){
return test["2154059444"]
}
})).filter(Boolean)
and simply render it app like this .
{ filteredData.map(test => <div>{test.name}</div>)}
Here is live link
This is simple. JSON is equivalent to Javascript object. So you can do something like result[0]["2154059444"]. You might want to use JSON.parse for converting the JSON string to Javascript object.

How to set parent component state from child of child

I am trying to finish this web challenge to land an Internship interview, and I have this problem with my code :
My webapp is a page that contains 4 main components :
- ProfilePage: Parent of all
- UserPanel : A side bar that shows user data via request to api
-TabBar : A container next to side bar that contains 2 components :
-> EventsTab : Shows events related to current user (same as the one displayed on user pane )
-> FriendsTab : Show friends of the current user (contains
"Fetch query={this.props.query} action={this.props.action}/")
-> Fetch : The component receives which call to make to the API through its query prop. It also calls the proper handler function explained below to handle different calls ( events, friends, userpanel )
My approach after a good amount of research and some coffee, was to Lift all the states Up to my ProfilePage Container, and I am now able to display user data in the UserPanel component,
I am using a handler to call a function getChildUser(user) with the user being the axios response.data directly from the Fetch Component, thus, getting the response from Fetch .
To give you a better idea, here is an example of a "/api/players/4" GET Response :
{
"id": 1,
"first_name": "Foo",
"last_name": "Bar",
"company": "Martin, Hi and Dumont",
"city_name": "Andreberg",
"last_seen": "2018-10-08T12:23:13.687Z",
"picture": "https://s3.amazonaws.com/uifaces/faces/twitter/rawdiggie /128.jpg",
"total_events": 93,
"total_friends": 83
}
And the handler :
this.getChildUser = this.getChildUser.bind(this);
this.getFriendsList = this.getFriendsList.bind(this);
//...
getChildUser(user) {
this.setState({
user: {
playername: user.first_name + " " + user.last_name,
picture: user.picture,
city: user.city_name,
last_seen: user.last_seen,
events: user.total_events,
friends: user.total_friends,
company: user.company
}
});
}
This Handler is called on the "UserPanel query="/players/5/" action={this.getChildUser}" inside of ProfilePage where we have "Fetch query={this.props.query} action={this.props.action} ", then we display the player data :
//.
<Card.Title> {this.props.user.events} </Card.Title>
//.
Finally, on our 'Fetch' :
axios
.get(API + "/" + this.props.query)
.then(response => this.props.action(response.data));
Now the I did the same thing to get using the same Fetch component, to retrieve the list of friends, but I just can't manage to get it working, i figured it has something to do with the formatting of the response because the friends response is as follows :
When calling "/api/friends/5"
[
{
"id": 18508,
"first_name": "Elisa",
"last_name": "Caron",
"company": "Carre, Rolland and Rodriguez",
"city_name": "West Louisshire",
"last_seen": "2017-11-14T09:31:52.026Z",
"picture": "https://s3.amazonaws.com/uifaces/faces/twitter/skkirilov/128.jpg",
"total_events": 193,
"total_friends": 25
},
{
"id": 92653,
"first_name": "Louis",
"last_name": "Bertrand",
"company": "Nicolas, Faure and Lemaire",
"city_name": "Port Ambretown",
"last_seen": "2018-06-22T11:14:12.862Z",
"picture": "https://s3.amazonaws.com/uifaces/faces/twitter/taybenlor/128.jpg",
"total_events": 113,
"total_friends": 135
}
]
I tried using this handler: in this case the name is getFriendsList
I realize it's a nested object field, but I couldn't figure out a way to fix it.
getFriendsList(friendsList){
this.setState({
friendsList : [
user: {
playername: friendsList.user.first_name + " " + friendsList.last_name,
picture: friendsList.user.picture,
events: friendsList.user.total_events,
friends: friendsList.user.total_friends,
},
]
})
}
This time we pull then info from "Fetch" by calling getFriendsList(response.data) trough our "FriendsTab" component then "TabBar" then back to "ProfilePage"
I get the error : _this.props.friendsList
" TypeError: _this.props.friendsList is undefined " in my component
Thank you !
I tried transforming the json response from the "Fetch" into an array, changing the friendsList structure ( though I'm not sure I've done it right )
Here is my github repository if you want to look it up more in detail
https://gitlab.com/mRamzi/mybchallenge
EDIT:
I can confirm that the problem comes from axios not correctly puttin data in my state, using react dev tools I noticed that props are passed but still empty, the getFriendsList() did not do it work, still trying to solve it
I have managed to resolve the problem, I will just go ahead and give the details in case someone faces the same issue:
The issue was indeed caused by the formatting of my json response (axios's response.data) that contained nested objects, i had to map over the friendsList and get the values.

How to Open Large Data using ng-href or ng-click in new window in AngularJS [duplicate]

This question already has an answer here:
How to Pass the data from Main Window to Child Window to display large data in table using AngulaJS
(1 answer)
Closed 6 years ago.
Can some one help me putting the DATA value new window .
I want to make td cell with DATA name as hyperlink . If I click that DATA it should open new window to show the value .
Demo
JSON Data
{
"58231e66982cf7857fee2cb5": {
"_id": {
"$id": "58231e66982cf7857fee2cb5"
},
"RECEIVETIME": {
"sec": 1478696550,
"usec": 529000
},
"OPERATION": "Operation 1",
"DATA" : "kdsjfkdjfkdjfkjdjfjdsfjdsilkjdkfljdsklfjkdlsjfkldsjflkdsjf",
"ACCOUNTNUMBER": "account",
"STATUS": "SUCCESS",
"MESSAGELOGCREATIONDATE": {
"sec": 1478696550,
"usec": 537000
}
},
"58231e681b58b970137b56aa": {
"_id": {
"$id": "58231e681b58b970137b56aa"
},
"RECEIVETIME": {
"sec": 1478696552,
"usec": 961000
},
"OPERATION": "Operation 2",
"DATA" : "dfdfdfkoooooooooooookdkfdkfodkfldkffdfd",
"ACCOUNTNUMBER": "account",
"STATUS": "FAIL",
"MESSAGELOGCREATIONDATE": {
"sec": 1478696552,
"usec": 961000
}
}
}
Currently I am using {{list.DATA}} show the data in the cell, But I want create hyperlink and once user clicks that link it should open new window to show the data. Since my DATA value is around 1000 lines. Can someone help me in approaching this.
And Is there way I can decode the Value of DATA in UTF-8 as the data value is encoded in UTF-8
Thanks in advance.
<tr class="features" ng-repeat="list in opMessageLogs">
<td>{{list._id.$id}}</td>
<td>{{list.OPERATION}}</td>
<td>{{list.STATUS}}</td>
<td>{{list.DATA}}</td>
</tr>
For a new tab, you need to create a link, but there's limit on a link (url) length, 2000 characters
Link here
what you can do is create a new route in angular that will take the param _id and then you can get the data by a http call or from service.
And for decoding/encoding utf-8
function encode_utf8(s) {
return unescape(encodeURIComponent(s));
}
function decode_utf8(s) {
return decodeURIComponent(escape(s));
}
Hope this helps..
To achieve this, you need to do following steps:
Create a state with a parameter i.e.
$stateProvider.state('openTab', {
'url' : '/link/:id',
'templateUrl': 'abc.html'
});
Use it this way in html.
<td> <a ui-sref="openTab({'id': list.DATA})" target="_blank">Click Here</a></td>

Firebase simple REST DELETE?

My data in firebase looks like the below. I am reading https://www.firebase.com/docs/rest/api/ and its weird, I am trying to remove an item.
burning-*
contacts
-K7qAf6egBeg5l3e_Gjc
name: "Ind"
phonenumber: "(408) ***-***"
uid: "1"
-K7qB8Afu7bIm9LUtV68
name: "Paul Bhayya"
phonenumber: "(408) ***-***"
uid:"2"
Inside angular.js I am making this call inside a custom directive of mine.
$http.delete(Firebaseurl + '/contacts/'+scope.contact.name+'/.json').then(function(result) {
console.log(result);
});
The api is not making sense to me, I see the problem might be that my data is now nested inside a key with a weird ID i.e -K7qAf6egBeg5l3e_Gjc.
So I am wondering how can I make a call to delete an item by the key name so if client side that contact is clicked say Ind gets clicked then I tell Firebase to delete the contact with that name. Maybe ID is better, but whatever works.
EDIT:
FYI I parsed the Firebase object selectedContacts is the result of the GET method for the objects. It wasnt formatted very well for my angular code so I turned it into a clean array of objects and I am using it to compare to other set of data to pass into the $scope
Object.keys(selectedContacts.data).forEach(function(key) {
selectedContactsArray.push(selectedContacts.data[key]);
});
selectedContactsArray.filter( function( item ) {
for( var i=0, len=usersContacts.length; i<len; i++ ){
if( usersContacts[i].name == item.name ) {
usersContacts[i]['selectedContact'] = true
}
}
});
To get a user by their name:
...firebaseio.com/contacts.json?orderBy="name"&equalTo="Ind"&limitToFirst=1
You'll have to add an index to your security rules:
{
"rules": {
"contacts": {
".indexOn": ["name"]
}
}
}
With this index, the query will return an object like this:
{
"-K7qAf6egBeg5l3e_Gjc": {
"name": "Ind",
"phonenumber": "(408) ***-***",
"uid": "1"
}
}
You can read the key from there and then execute a REST DELETE request against
...firebaseio.com/contacts/-K7qAf6egBeg5l3e_Gjc.json
But as discussed in the comments to your question, you can also use AngularFire to do the same.

Association ExtJs MVC 4.2

ExtJS 4.2 MVC: I have two models ServiceM and CommentsM. ServiceM has association(hasmany) with CommentsM. I DIDNOT forget to add the requires section ServiceM. Proxy is an ajax type defined in the model itself. I also created stores for each. Coming to the view, I have a grid for viewing all the services which are derived on loading the application. itemdblclick event is used to provide a detailed view about the service which is a window extending a form. The form is popullated by the below code:
var ServiceDetailV = Ext.widget('alias name of the service detail view');
ServiceDetailV.down('form').getForm().loadRecord(record);
I have two questions here.
When using developer tools in google chrome, in the above code I place debugger; at the end. I have highlighted the record, right clicked and evaluated that part. I see the data part and raw part. what is this raw part. It has all the data which the server is giving me(payload), even the nested comments section which is associated with the Service data.
I am able to popullate the fields in the form, but not the list of comments. the list of comments goes into a panel present in the form. How can I popullate the comments section.
JSON data:
{
"data": [
{
"id": 1,
"x": "some text",
"q": "some text",
"a": "some text",
"r":"some text",
"comments": [
{
"id": 87,
"commentDate": "date",
"description": "some text"
},
{
"id": 86,
"commentDate": "date",
"description": "some text"
}
]
} "total": 1,
"success": true}
Now, how can i access the comments field and poppulate the form with this data?
Please shed some knowledge on Associations ExtJs MVC.
Cheers!
Well, I took a step and got the solution for this. the raw parameter actually has the raw JSON payload. In the controller part I have handled it via a select event.
onSelectIssueShowComments : function(selection,record, index, eOpts) {
this.getComments().setRecord(record.raw);
}
I the view part
tpl : [ '<p>Previous Comments: ', '<tpl for="comments">',
'<p>{#}. {description} {commentDate}</p>', '</tpl></p>' ],
setRecord : function(record) {//this record here is record.raw
this.record = record;
if (record) {
this.update(record);
} else {
this.update(' ');
}
}
So it displays the array of comments in a Panel.

Resources