VueJS doesn't show data on a component but shows on console - json

I have two pages - Books and Book. I am trying to show some data on my Book page after clicking the single item from the Books page.
I have managed to fetch the JSON file which lists all the items on the Books page as well as a link to navigate to the Book page by id.
The problem I am facing is I can't fetch the data which is returned by JSON on the Book page. The data is hidden but console.log(response.data) shows response data on console without a problem.
Here is the route-link from the Books page which navigates a single Book:
<router-link :to="'/books/' + book.id"> Link </router-link>
And here is my Book component script
<script>
import LibraryDataService from "../services/LibraryDataService";
export default {
name: "Book",
data() {
return {
book: "",
};
},
methods: {
getBook(id) {
LibraryDataService.get(id)
.then((response) => {
this.book = response.data;
console.log(response.data);
})
.catch((e) => {
console.log(e);
});
},
},
mounted() {
this.getBook(this.$route.params.id);
},
};
</script>
Any help will be appreciated

Try to wait for response:
async mounted() {
await this.getBook(this.$route.params.id);
},

I have been able to solve the issue by modifiying response.data on the getBook method as this.book = response.data[0];

Related

Using async data for seo head elements in nuxt3

I am trying to create a site using data fetched from a directus instance.
Currently I have a layout component app.vue filling all seo meta tags using static default values hardcoded in that file.
So in the setup I am using:
useSeoMeta({
title: () => "Static title"
})
which is not creating the desired output. No title is rendered.
Also for a post component I want to overwrite the values from layout using data fetched from a remote source:
const { data: post, pending } = await useAsyncData('post', () => {
return getItemById({
collection: "collection_id",
filter: {
status: "published"
},
id: route.params.id,
}).then((data) => {
let ast = Markdoc.parse(data.content);
let transform = Markdoc.transform(ast);
data.content = Markdoc.renderers.html(transform);
useSeoMeta({
title: data.seo_title,
});
return data;
});
});
This is also not working as expected and serves different result, depending weather ssr is applied or not.
How would one implement a solution like this?

Vuejs getting data from local json

I got some json data in a local file the file is .txt file and the data is not directly accessible so I just changed the file format to .json and after that, I tried to get clean data to loop through with the code below.
I'm getting the data via computed in this component but I want to set this clean data as a prop to a child component.
I want to create many child components with clean data.
Thank you very much in advance!
Code:
<script>
export default {
name: 'Dashboard',
components : {
'my-table': mytable,
'my-search': search,
},
data: function() {
return {
casesDataList: [],
};
},
computed:{
ClearList: function(){
var casesDataList = this.casesDataList.map(function (neo){
return {ID: neo.Attributes[1].Value, Date: neo.FormattedValues[0].Value, Owner: neo.FormattedValues[1].Value};
});
return casesDataList;
}
},
created: function(){
this.getCasesData();
},
methods: {
getCasesData() {
fetch("Weather.json")
.then(response => response.json())
.then(data => (this.casesDataList = data.Entities));
},
}
};
</script>
You can pass the computed as a prop to the child directly:
<child :propname="ClearList"></child>
In the child:
export default {
props: ['propname'],
// ...
}

Data from API is displaying in the console but not in the DOM, why?

I'm learning React and a little about API's. I'm using the Destiny 2 API as a starting API to try to wrap my head around how they work.
Here is my Api.js file:
import React, { Component } from 'react';
import './style.css';
import axios from 'axios';
class Api extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
};
}
componentDidMount() {
let config = {
headers: {
'X-API-KEY': 'key-here',
},
};
axios
.get('https://www.bungie.net/Platform/Destiny2/4/Profile/4611686018484544046/?components=100', config)
.then((response) => {
console.log(response);
this.setState({
data: response.data,
});
});
}
render() {
const { item } = this.state;
return (
<div>
{Array.isArray(item) &&
item.map((object) => <p key={object.data}>{object.data.Response.profile.data.userInfo.displayName}</p>)}
</div>
);
}
}
export default Api;
The data from the API is returned as an object that contains a nested array. I can get the data to display in the console no problem.
This is the layout of the response object output to the console:
I'm trying to grab the value of "displayName" and output it into the DOM, what am I doing wrong?
I have tried returning the data as JSON by doing:
response => {return(data.json())} and iterating through the json object using {Object.keys(this.state.data).map((key) => but I have still managed to only get data in the console and not in the DOM.
Is there anything that seems to be missing? I've been stuck with this problem for several days now!
EDIT: This is the whole response from the API call
{
"Response": {
"profile": {
"data": {
"userInfo": {
"membershipType": 4,
"membershipId": "4611686018484544046",
"displayName": "Snizzy"
},
"dateLastPlayed": "2019-04-05T14:28:30Z",
"versionsOwned": 31,
"characterIds": [
"2305843009409505097",
"2305843009411764917",
"2305843009425764024"
]
},
"privacy": 1
}
},
"ErrorCode": 1,
"ThrottleSeconds": 0,
"ErrorStatus": "Success",
"Message": "Ok",
"MessageData": {}
}
In the render function, where you destructure you state, you have the wrong property.
const { item } = this.state; should be const { data } = this.state;
More about destructuring here.
Also, you need to make changes here:
EDIT: Actually, your data isn't even an array. You don't have to iterate through it.
<div>
<p>{data.Response.profile.data.userInfo.displayName}</p>}
</div>
Let's do a check to make sure that we got back the api before running. You might be rendering before the api call is finished. Try using an inline statement.
{ item ? {Array.isArray(item) && item.map(object => (
<p key={object.data}>{object.data.Response.profile.data.userInfo.displayName}</p>
))}
:
<div>Loading...</div>

Calling a local json file and parsing data in ReactJS

I have the following json file. Right now, i have kept this in my ReactJS project itself locally. Later on planning to move in a server location.
abtestconfig.json
[
{
"abtestname": "expAButton",
"traffic": 1,
"slices":
[
"orange",
"blue"
]
},
{
"abtestname": "expTextArea",
"traffic": 0.5,
"slices":
[
"lightgrey",
"yellow"
]
}
]
I want to read and get data and parse it and apply in a function. I got some reference sample code and trying to use fetch api to react json file with the following code.
After reading this json file, i will have to pass the data in abtest function, as you can see now it's sending with hard coded value abtest('expAButton', 0.75).slices('orange', 'blue').run(function ()
I have the following doubts and wanted to get your guidance / clarification.
1. Is it correct way to read json file using fetch api? Is there any other best approach?
2. When I use fetch api like mentioned below, console log displays GET http://localhost:8080/abtesting/abtestconfig.json 404 (Not Found)
app.jsx file:
import './abtesting/abtestconfig.json';
class App extends React.Component {
constructor() {
super();
this.onClick = this.handleClick.bind(this);
this.onClickNewUser = this.handleNewUser.bind(this);
this.state = {
bgColor: '',
data: []
}
};
handleNewUser (event) {
abtest.clear();
window.location.reload();
}
render() {
return (
<Helmet
/>
<p><b>A/B Testing Experience</b></p>
<div className="DottedBox">
<p><button id = "newUserButton" onClick = {this.onClickNewUser} style={{backgroundColor:"red"}}>Welcome and click here</button></p>
</div>
);
}
handleClick () {
abtest('expAButton', 0.75).slices('orange', 'blue').run(function () {
expAButton.style.backgroundColor = this.slice.name;
});
}
setStyle (stylecolor) {
this.setState({
bgColor: stylecolor
})
}
componentDidMount () {
this.handleClick();
fetch('./abtesting/abtestconfig.json').then(response => {
console.log(response);
return response.json();
}).then(data => {
// Work with JSON data here
console.log(data);
}).catch(err => {
// Do something for an error here
console.log("Error Reading data " + err);
});
}
}
export default hot(module)(App);

Outputting JSON Data from Local Web Server onto Ionic App using Angular

CHALLENGE
I am trying to output the following JSON via Angular JS into my Ionic Framework Starter Side-Menu App and currently the only response that I get from my Console Log is the following:
0 825606 log ApiEndpoint, [object Object]
1 825809 log Got some data: , [object Object]
1 825883 log Got some data: , [object Object]
Unfortunately as a result of this, I'm unable to display my product list within products.html
JSON Output from my Web Server [node.js server with MongoDB database local]
My webserver output is available at http://localhost:8080/api/products
[
{
_id: "55be0d021259c5a6dc955289",
name: "Apple",
price: 2.5
},
{
_id: "55be0d541259c5a6dc95528a",
name: "Oranges",
price: 1.5
},
{
_id: "55be0d6c1259c5a6dc95528b",
name: "Pear",
price: 3
},
{
_id: "55be0d6c1259c5a6dc95528c",
name: "Orange",
price: 3
}
]
services.js
angular.module('starter.services', [])
.factory('Api', function($http, ApiEndpoint) {
console.log('ApiEndpoint', ApiEndpoint)
var getApiData = function() {
return $http.get(ApiEndpoint.url + '/products')
.then(function(products) {
console.log('Got some data: ', products);
return products;
});
};
return {
getApiData: getApiData
};
})
controllers.js [Relevant code]
.controller('ProductsCtrl', function($scope,Api) {
$scope.products = null;
Api.getApiData()
.then(function(result) {
$scope.products = result.products;
})
ionic.project
{
"name": "grocerApp",
"app_id": "",
"proxies": [
{
"path": "/api",
"proxyUrl": "http://cors.api.com/api"
}
]
}
products.html [to show off the output]
<ion-view view-title="The Grocer Shop">
<ion-content>
<ion-list>
<ion-item ng-repeat="product in products">
<a class="item item-thumbnail-left" href="#/app/products/{{product.id}}">
<img src="http://loremflickr.com/30/30/apples">
<h2>{{product.name}}</h2>
<p>EUR {{product.price}} per kilogram</p>
</a>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
app.js [Relevant code]
angular.module('starter', ['ionic', 'starter.controllers','starter.services'])
.constant('ApiEndpoint', {
url: 'http://localhost:8080/api'
})
Unfortunately the following links did not help me out :
Ionic/Angular App not reading json data from api
Getting data from a json file in IONIC using AngularJS
I also double checked the file path and the JSON loads well in my local browser window[I am using Chrome with CORS extension enabled - https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en ]
QUESTION
How can I get my JSON Data from my local webserver into my products.html file?
your service and controller is a bit wrong try the following
services.js
angular.module('starter.services', [])
.factory('Api', function($http, ApiEndpoint) {
console.log('ApiEndpoint', ApiEndpoint);
var getApiData = function() {
return $http.get(ApiEndpoint.url + '/products');
};
return {
getApiData: getApiData
};
})
controllers.js
.controller('ProductsCtrl', function($scope,Api) {
$scope.products = null;
Api.getApiData().then(function(result) {
$scope.products = result.data;
});
EDIT: Further explanations
So your first problem was returning a promise and trying to resolve it in multiple places.
return $http.get(ApiEndpoint.url + '/products')
.then(function(products) {
console.log('Got some data: ', products);
return products;
});
Api.getApiData()
.then(function(result) {
$scope.products = result.products;
})
Best practice is that your service returns the promise, which $http already does. You should then handle how that promise is resolved in the controller so basically what I did was just remove the .then from your factory.
The next error you had was trying to call result.products inside then function. How a promise resolves is nesting the entire body in a json object with the data attribute. So in this case your response is looking like {'data': [array_of_fruit]}. If your response were to return {'products':[array_of_fruit]} then you would still have to access like result.data.products.
Hope this helps.