So here is the set up:
I have simple nodejs backend (based on express and mongoose), which responds to GET request with some JSON (in the form of Object of objects).
So after I get the response, I want to render a component, for each elements of said Object of objects. If it was array, I could simply use array.map(), and render a component in the callback function. But since what I have, is Object, i can not use that.
So... Should I return and Array from the backend. If so how do I tell mongoose to return the result of model.find() in the form of array.
Or should I convert the object to array in the frontend? In this case, how would I do it without putting it through a loop of some sort?
Lastly, I tried to make it work like so:
render: function() {
//console.log('render TodoList componenr');
var items = this.state.todoItems;
return(
<ul>
{for (var item in items){
console.log(item);
}}
</ul>
);
}
To which i get this error:
Uncaught SyntaxError: embedded: Unexpected token (30:9)
28 | return(
29 | <ul>
> 30 | {for (var item in items){
| ^
31 |
32 | }}
33 | </ul>
Which is super weird, as it points to empty location?
Any ideas how could make this work?
To iterate over an object you could use Object.keys like so:
Object.keys(yourObject).map(function(key) {
return renderItem(yourObject[key]);
});
The method returns an array of a given object's own enumerable properties, in the same order as that provided by a for...in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well).
It's supported by IE >= 9, Chrome >= 5, Safari >= 5, Firefox >= 4.
You can setting the object.map function equal to a variable outside the return function and then just return that variable.
render() {
var article = this.props.article;
var articleNodes = article.map(function(article, key){
if(article.iurl == ""){
article.iurl = "basketball.jpg";
};
return(
<li key={key}>
<Image item={article}/>
<div className="post-basic-info">
<h3><a target="_blank" href={article.url}>{article.title}</a></h3>
<span><label> </label>{article.team}</span>
<p>{article.description}</p>
</div>
</li>
)
});
return(
<div>
{articleNodes}
</div>
)
}
Related
I am using axios to access the OMDB api. The returned value is saved to a ref([]) object called ombdRatings in my vue component, and I'm trying to access these values to be displayed in the DOM. Here's the returned json:
{"Title":"Parasite","Year":"1982","Rated":"R","Released":"12 Mar 1982","Runtime":"85 min","Genre":"Horror, Sci-Fi","Director":"Charles Band","Writer":"Alan J. Adler, Michael Shoob, Frank Levering","Actors":"Robert Glaudini, Demi Moore, Luca Bercovici","Plot":"In a post-apocalyptic USA, a doctor/scientist infected with a new strain of parasite ends up in a small desert town, trying to find a cure.","Language":"English","Country":"United States","Awards":"N/A","Poster":"https://m.media-amazon.com/images/M/MV5BMTFlZDVjMDMtODkwNS00MTM3LWJiMzQtY2IxN2JiNWZjMWUxXkEyXkFqcGdeQXVyMTQxNzMzNDI#._V1_SX300.jpg","Ratings":[{"Source":"Internet Movie Database","Value":"4.0/10"},{"Source":"Rotten Tomatoes","Value":"17%"}],"Metascore":"N/A","imdbRating":"4.0","imdbVotes":"2,574","imdbID":"tt0084472","Type":"movie","DVD":"30 Oct 2017","BoxOffice":"N/A","Production":"Embassy Pictures","Website":"N/A","Response":"True"}
The ratings are stored in an array in my object. When I try to access the first item on the array to display in the DOM like: {{ omdbRatings.Ratings[0] }} then I get an error like
Uncaught (in promise) TypeError: Cannot read properties of undefined
(reading '1')
I can access other items in the object, but I don't know how I can access this array in my DOM with interpolation.
when axios is not done ,ratings and Value are undefined,so it is wrong. you can need to ratings is exist。you wirte code:
<div v-if="omdbRatings&&omdbRatings.Ratings&&......">.....</div>
This is tedious.
Simple,code is right.
in js,you can:
console.log(omdbRatings?.Ratings?.[0]?.Value||'--');
but template,you need template supposed Optional_chaining:
export const optionalChaining = (obj, ...rest) => {
let tmp = obj;
for (let key in rest) {
let name = rest[key];
tmp = tmp?.[name];
}
return tmp || "";
}
so,template use:
{{optionalChaining(omdbRatings,"Ratings",'0','Value')||'--'}}
I've been trying to use react-router to define a series of nested components/routes w/ optional params, but also separated by path placeholders.
i.e.
/list
/list/1
/list/items
/list/1/items
/list/1/items/1
I would assume the two <Route> paths would be something like:
/list/:listId?
and
`${match.url}`/items/:itemId?`
But alas.. "items" always ends up being accepted as the listId param, and therefore, the sub-routing for /items never matches.
I have a generic example I've coded here (doesn't accomplish a solution): https://stackblitz.com/edit/nesting-w-optional-params-react-router
I see examples all over the internet for /root/:id1?/:id2? but nothing for what I'm trying to do where I have a placeholder between the params: /root/:id1/placeholder/:id2.
Is this possible to do w/ react-router v4+ ??
Figured out a solution utilizing RR's children pattern, to always render the nested route/component, but then inside the component use path-to-regexp directly to do route matching and to grab relevant route params from props.location.pathname.
Relevant bit of code:
render() {
const pathRe = new PathToRegexp('/foo/:fooId?/bar/:barId?')
const match = pathRe.match(this.props.location.pathname)
if (!match) {
return null
}
const barId = (this.props.match && this.props.match.params.barId) || match.barId
return <h1>Bar <em>{barId}</em></h1>
}
https://stackblitz.com/edit/nesting-w-optional-params-react-router-solution
I try to access to my data json file:
[{"id":1,"name":"Maria","project":[{"id":5,"name":"Animals"},{"id":6,"name":"Cats"}]}
This is my approach:
data[0].name;
But like this I get only the result:
Animals
But I would need the result:
Animals, Cats
You are accessing only the name property of 0th index of project array.
To access all object at a time you need to loop over the array.
You can use Array.map for this.
var data = [{"id":1,"name":"Maria","project":[{"id":5,"name":"Animals"},{"id":6,"name":"Cats"}]}]
var out = data[0].project.map(project => project.name).toString()
console.log(out)
If that's your actual data object, then data[0].name would give you "Maria". If I'm reading this right, though, you want to get all the names from the project array. You can use Array.map to do it fairly easily. Note the use of an ES6 arrow function to quickly and easily take in the object and return its name.
var bigObject = [{"id":1,"name":"Maria","project":[{"id":5,"name":"Animals"},{"id":6,"name":"Cats"}]}];
var smallObject = [{"id":5,"name":"Animals"},{"id":6,"name":"Cats"}];
console.log("Getting the names from the full array/data structure: "+bigObject[0].project.map(obj => obj.name))
console.log("Getting the names from just the project array: "+smallObject.map(obj => obj.name))
EDIT: As per your comment on the other answer, you said you needed to use the solution in this function:
"render": function (data, type, row) {if(Array.isArray(data)){return data.name;}}
To achieve this, it looks like you should use my bottom solution of the first snippet like so:
var data = [{"id":5,"name":"Animals"},{"id":6,"name":"Cats"}];
function render(data, type, row){
if(Array.isArray(data)){
return data.map(obj => obj.name);
}
};
console.log("Render returns \""+render(data)+"\" as an array.");
I'm learning React and have set up a small test app that makes an Ajax call that returns a JSON object that I want to iterate over in the return method of my component. I've tried everything I can think of and have googled this, but like an hour later I'm still stumped.
Here is what I have...
render() {
const { vals } = this.state;
return (
<div>
{/* note that this correctly outputs the value of vals[key]: {vals['key']} */}
Object.keys({vals}).map((key, index) => (
<p key={index}> this is my key {key} and this is my value {vals[{key}]} </p>
))
</div>
)
}
What am I doing wrong here? Any recommendations on a good reference for ES6/JSX? I've been struggling with simple things, with no good way to look up this info.
{vals} extracts out the vals property from an object. Hence Object.keys({vals}) is incorrect as vals is already an object. Likewise, it should be {vals[key]} instead of {vals[{key}]}.
render(){
const {vals} = this.state; // Essentially does: const vals = this.state.vals;
return (
<div>
{
Object.keys(vals).map((key, index) => (
<p key={index}> this is my key {key} and this is my value {vals[key]}</p>
))
}
</div>
)
}
If vals is an object containing { a: 1, b: 2}, Object.keys(vals) will get you ['a', 'b'] and in the first iteration of the map, key will be 'a' and to access the value, do vals[key] which is essentially vals['a'] => 1.
I think you are confused by the Object destructuring syntax. It's really quite simple as it's just syntactic sugar over ES5 JavaScript (most ES6 is just sugar). Have a read at MDN's docs on Destructuring assignment to understand it better.
Let's say I have a JSON array of data, something like:
[ {"name":"parijat","age":28},
{"name":"paul","age":28},
{"name":"steven","age"27},
...
]
that is part of my model, and this model is setup like this:
App.UserRoute = Ember.Route.extend({
model:function(){
return App.User.FIXTURES ; // defined above
}
});
I want to get the unique ages from this JSON array and display them in my template, so I reference the computed properties article and read up a little on how to enumerate Ember Enumerables, to eventually get this:
App.UserController = Ember.ArrayController.extend({
ages:function(){
var data = this.get('content');
var ages = data.filter(function(item){
return item.age;
});
}.property('content');
});
Now the above piece of code for controller is not correct but the problem is that it doesn't even go into data.filter() method if I add a console.log statements inside. IMO, it should typically be console logging as many times as there exist a App.Users.FIXTURE. I tried using property('content.#each') which did not work either. Nor did changing this.get('content') to this.get('content.#each') or this.get('content.#each').toArray() {spat an error}.
Not sure what to do here or what I am completely missing.
Filter is used for reducing the number of items, not for mapping.
You can use data.mapBy('age') to get an array of your ages:
ages:function(){
return this.get('content').mapBy('age');
}.property('content.#each')
or in your handlebars function you can just use the each helper:
{{#each item in controller}}
{{item.age}}
{{/each}}