I'm using Laravel and Vue connected via API,
Everything works fine.
I asked to get offer via method from Vue:
getOffer(id) {
this.$http.get('http://127.0.0.1:8000/api/offers/'+id)
.then(response => response.json())
.then(result => this.offer = result)
}
},
And I recived this:
{
"body": "xx"
"title": "yy"
}
and then put it into offer variable:
data() {
return {
offer: {
title:'',
body:''
}
}
},
and I used it into template
<div>
<h3 class="headline mb-0">{{offer.title}}</h3>
<div>
<br>
{{offer.body}}</div>
</div>
easy, all works fine
Now I decided to use Laravel Resource. This is wrapping data into "data" object within json response, so I got now this:
{
"data": {
"body": "xx"
"title": "yy"
}
}
and my template is blank - can anyone tell me how should I change the code, to work with new data object? And how I could work with it, when It will contain more objects, like:
{
"data": {
"body": "xx"
"title": "yy"
},
"data2":{
"body": "xx"
"title": "yy"
},
}
etc.
getOffer function should be modified to use result.data instead of raw result:
getOffer(id) {
this.$http.get('http://127.0.0.1:8000/api/offers/'+id)
.then(response => response.json())
.then(result => this.offer = result.data)
}
},
now it works again
Related
In my app I am trying to make a feature that when the user click the tag it shows him all the products that have this tag...
My search request is being made with GET method over an API call... so what I am trying to achieve is that on a tag click the tag value is sent as a parameter in the url and thus returning all products with this tag in a new page... My API call works in POSTMAN but I am having trouble implementing it in Angular...
So my main questions and issues are:
How to make the tag clickable so it sends the value with the api request
How to add routerlink to the tag so it redirects to new page where it shows all the products with this tag
I am very new to Angular so please help :)
This is the image how tags are displayed in the app:
Here is my code:
HTML in home.page.html for outputing the tags:
<ion-chip *ngFor="let tag of tags">
<ion-label>{{ tag.tags }}</ion-label>
</ion-chip>
Code for search API in search.service.ts:
searchByTagCall(tag: string) {
return from(Preferences.get({key: 'TOKEN_KEY'})).pipe(
switchMap(token => {
const headers = new HttpHeaders().set('Authorization', `Bearer ${token.value}`);
let params = new HttpParams();
params = params.append('tag', tag);
return this.httpClient.get(`${environment.apiUrl}search`, {headers, observe: 'response', params});
}),
catchError(err => {
console.log(err.status);
if (err.status === 400) {
console.log(err.error.message);
}
if (err.status === 401) {
this.authService.logout();
this.router.navigateByUrl('/login', {replaceUrl: true});
}
return EMPTY;
}),
);
}
Code of home.page.ts:
searchByTag() {
this.searchService.searchByTagCall(tag).subscribe(
(data: any) => {
/* what do I put here? */
},
error => {
console.log('Error', error);
});
}
My JSON looks like this:
{
"tags": [
{
"tags": "fruit"
},
{
"tags": "sour"
},
{
"tags": "sweet"
},
{
"tags": "frozen"
},
{
"tags": "fresh"
},
{
"tags": "vegetable"
},
{
"tags": "raw"
}
]
}
Do the following changes:
home.page.html:
<ion-chip *ngFor="let tag of tags">
<ion-label class="tag" (click)="searchByTag(tag.tags)">{{ tag.tags }}</ion-label>
</ion-chip>
home.page.scss:
// In case you need to change the cursor to be the hand icon
.tag {
cursor: pointer;
}
home.page.ts:
constructor(/*whatever parameters you have in your constructor already*/, private router: Router, private dataService: DataService) {
// Whatever code you have in your constructor
}
searchByTag(tag: string) {
this.searchService.searchByTagCall(tag).subscribe((data: any) => {
// 1. Store the data in some service so it will be accessible for the other page
this.dataService.tagData = data;
// 2. Navigate to the other page (you can store the tag in the route params if you need it)
this.router.navigate(['/tagPage/', tag]);
},
error => {
console.log('Error', error);
});
}
Here is my code:
<ul>
<li v-for="value in RandomTopic" :key="value.id">{{ value.title }}</li>
</ul>
export default {
data() {
return {
RandomTopic: null
}
},
mounted() {
///some method to get data from remote server
console.log(res.data);
this.RandomTopic = res.data;
}
}
I want to render all the data from the remote server in front end. However, after the program ran, it reports this error:
Cannot set property 'RandomTopic' of undefined ; at api request success callback function
TypeError: Cannot set property 'RandomTopic' of undefined
The console.log(res.data); log the JSON successfully so it seems not the problem of AJAX or remote server.
And also, here is a sample of the JSON:
[
{
"id": 421,
"title": "sample1",
"image_url": "bus.png"
},
{
"id": 535,
"title": "sample78",
"image_url": "car.png"
}
]
What's wrong with my code ? I am a beginner of Vue 3, please help me.
As per the error you mentioned, Issue is basically related to the scope of this. Looks like you are using regular function instead of arrow function ( => {...}) which don't provide their own this binding (it retains this value of the enclosing lexical context).
Reference - Arrow function
.then(res => {
this.RandomTopic = res.data;
})
I am currently creating a bolt slack app with JavaScript that needs to send out an HTTP POST request to an external webhook when a button click occurs. Sending data to my slack app from external sources is simple enough using the slack webhook provided in the app settings, but I can't seem to figure out how to send a message from my app.js file. My app is currently in Socket Mode since I didn't want to set up a Request URL after my Ngrok url didn't seem to work with the verification in slack, and there doesn't seem to be a lot of documentation on this issue. Of the documentation I did find, https://api.slack.com/apis/connections/socket-implement#connect, I wasn't sure how to implement apps.connections.open into my JavaScript file. I am fairly new to JavaScript and HTTP Requests, so any help would be greatly appreciated. I am also using the Bolt app package for slack, below is my code.
const { App } = require('#slack/bolt');
// Initializes your app with your bot token and signing secret
const app = new App({
token: "xoxb-",
signingSecret: "",
appToken: "xapp-",
socketMode: true,
port: process.env.PORT || 3000
});
app.message('Hey bot', async ({ message, say }) => {
// say() sends a message to the channel where the event was triggered
await say({
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": `You made a request <#${message.user}>?`
}},
{
"type": "divider"
},
{
"type": "input",
"element": {
"type": "plain_text_input",
"action_id": "plain_text_input-action"
},
"label": {
"type": "plain_text",
"text": "Error Message",
"emoji": true
}
},
{
"type": "input",
"element": {
"type": "plain_text_input",
"multiline": true,
"action_id": "plain_text_input-action"
},
"label": {
"type": "plain_text",
"text": "Description of Error",
"emoji": true
}
},
{
"type": "input",
"element": {
"type": "plain_text_input",
"action_id": "plain_text_input-action"
},
"label": {
"type": "plain_text",
"text": "Aditional notes?",
"emoji": true
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Submit",
"emoji": true
},
"value": "click_me_123",
"action_id": "button_click"
}
]
}
]
});
});
app.action('button_click', async ({ body, ack, say }) => {
// Acknowledge the action
await ack();
say("No Flagged Issues");
// My HTTP POST REQUEST would go here, IF I HAD ANY!
}
});
(async () => {
// Start your app
await app.start(process.env.PORT || 3000);
console.log('⚡️ Bolt app is running!');
})();
At the end of the day, Bolt apps are just plain old JS apps, so there's nothing particularly special you would need to do to make a HTTP POST from inside your app.action().
There's a bunch of libraries out there, but one of the more popular ones is Axios. After importing it, you'd just have code like this inside your app.action method
axios.get('https://www.nodesource.com/')
.then(function (response) {
// handle success
console.log(response);
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
// Using async/await
async function getUser() {
try {
const response = await axios.get('https://www.nodesource.com/');
console.log(response);
} catch (error) {
console.error(error);
}
}
This snippet is by no means idiomatic JS, but it's enough to get you going.
I have a json, viewable at https://imgur.com/a/F3kV29F
or here https://dweet.io/get/dweets/for/shyam__5
In python, I am able to print the yearlyWatts by doing:
print(collection[1]['content']['yearlyWatts'])
where collection is the json, done by:
collection = (dweepy.get_dweets_for('shyam__5'))
I am trying to do the same thing in Javascript. Currently, I have done:
getCryptoCurrencyInfo(5)
.then(currencyInfo => {
console.log(currencyInfo[1].yearlyWatts)
This does not work, I get no output.
Please do not pay attention to the function getCryptoCurrencyInfo, I would really appreciate if someone could tell me what to write in the console.log(HERE) in order to output the yearly watts of 111255.51
Any help would be appreciated. Thanks!
Suppose you want a single yearlyWatt.
const data = {
"this": "succeeded",
"by": "getting",
"the": "dweets",
"with": [{
"thing": "shyam__5",
"created": "2020-07-03T08:38:01.184Z",
"content": {
"test": "test"
}
},
{
"thing": "shyam__5",
"created": "2020-07-03T08:37:58.068Z",
"content": {
"yearlyWatts": 111429.4
}
}
]
}
console.log(data.with[1].content.yearlyWatts)
I figured out how to do it thanks to xMayank's help.
In the backend module, the code is:
import { fetch } from 'wix-fetch'
export function getCryptoCurrencyInfo() {
const url = 'https://dweet.io/get/dweets/for/shyam__5'
console.log(url)
return fetch(url, { method: 'get' }).then(response => response.json())
}
To get it to work, the site page (front end) says this:
// For full API documentation, including code examples, visit https://wix.to/94BuAAs
import { getCryptoCurrencyInfo } from 'backend/serviceModule'
import { fetch } from 'wix-fetch'
$w.onReady(function() {
//TODO: write your page related code here...
getCryptoCurrencyInfo().then(currencyInfo => {
const data = currencyInfo
console.log(data.with[1].content.yearlyWatts)
console.log(data.with[2].content.monthlyWatts)
console.log(data.with[3].content.currentDailyCarbonSaved)
console.log(data.with[4].content.currentDailyWatts)
})
})
considering global_obj your json_object, you can do this
global_obj.with.find(element => element.thing==="shyam__5");
componentWillMount() {
console.log('Component WILL MOUNT!')
axios.get('/channels').then( (res) => {
//console.log(res.data.data.playList);
let playlists = [];
res.data.data.playList.map((value, key) => playlists.push(new Audio(value.url)));
this.setState((prevState) => {
return { audioList: playlists, categories: res.data.data.playList }
}, () => console.log(this.state.audioList));
}).catch( (err) => {
console.log(err);
});
}
**I also call this in componentDidUpdate() **
The above code that I used in my ReactJS web app to retrieve data from my DB that looks something like:
{
"_id": {
"$oid": "5a2b903abcf92a362080db4f"
},
"name": "test",
"playList": [
{
"url": "https://p.scdn.co/mp3-preview/a3fd5f178b7eb68b9dba4da9711f05a714efc966?cid=ed36a056ee504173a3889b2e55cbd461",
"artist": "Lil Pump",
"songName": "D Rose",
"_id": {
"$oid": "5a2c5631e54ca10eb84a0053"
}
},
{
"url": "https://p.scdn.co/mp3-preview/155643656a12e570e4dda20a9a24d9da765b9ac5?cid=ed36a056ee504173a3889b2e55cbd461",
"artist": "Tee Grizzley",
"songName": "From The D To The A (feat. Lil Yachty)",
"_id": {
"$oid": "5a2c5631e54ca10eb84a0054"
}
}
],
"__v": 0
}
I retrieve the url for each songs and store it inside my state this.state.audioList to make a playable list.
I access each song with an index
So, this.state.audioList[0] would be the first song.
When I try to play this music by doing
this.state.audioList[0].play(), this totally works fine.
The problem is when I try to pause it.
this.state.audioList[0].pause() does not pause the song for some reason.
I am assuming that it is because the this.state.audioList is getting updated every time and the Audio object that I am trying to pause is a new object that has nothing to do with the one currently being played.
Am I right? If so, is there a solution to this issue?
Please help!
That should work in componentWillMount although componentDidMount is preferred, see : https://reactjs.org/docs/react-component.html#componentdidmount
Quoted from this link (remote endpoint being your axios URL here) :
If you need to load data from a remote endpoint, this is a good place to instantiate the network request.
But you're almost certain that won't work if you put your axios.get() request in componentDidUpdate, because this method is called each time your component has been updated and re-rendered.
From the React Component Lifecycle document, you'll see that componentWillMount and componentDidMount both stay in the Mounting section (that is, they are called only once when the components DOM element are inserted in the DOM), whereas componentDidUpdate is in the Updating section, and therefore is called each time your component's state or props are changed (what happens when your axios.get() promise is fulfilled).
Also, as map returns an array, why not assign its returned value to your audioList ? Here is an example that you may want to try (untested though, sorry !):
componentDidMount() {
console.log('Component DID MOUNT!')
axios.get('/channels').then( (res) => {
//console.log(res.data.data.playList);
this.setState({
audioList: res.data.data.playList.map(value => new Audio(value.url)),
categories: res.data.data.playList
});
}).catch( (err) => {
console.log(err);
});
}
Hope this helps!