Popular New Releases in Lastfm
nuclear
bc8b7b
web-scrobbler
v2.58.0
TauonMusicBox
v7.1.2
pylast
5.0.0
Last.fm-Scrubbler-WPF
Beta 1.26
Popular Libraries in Lastfm
by nukeop typescript
8707 AGPL-3.0
Streaming music player that finds free music for you
by web-scrobbler javascript
1860 MIT
Scrobble music all around the web!
by dlrudie csharp
860 GPL-3.0
Snip will get the artist, track, and album information from Spotify and iTunes, and save the information to a text file.
by taizilongxu python
804 MIT
:radio: douban.fm based on Python
by Taiko2k python
802 GPL-3.0
The Linux desktop music player from the future! :city_sunset:
by pylast python
498 Apache-2.0
A Python interface to Last.fm and Libre.fm
by simple-last-fm-scrobbler java
483 Apache-2.0
Simple Scrobbler, for Android -- last.fm, libre.fm & ListenBrainz
by generative-music javascript
483 MIT
A collection of generative music pieces for generative.fm
by Make-Magazine c
400
Raspberry Pi Automated FM Radio Script
Trending New libraries in Lastfm
by RudeySH javascript
126 GPL-3.0
Bulk edit your scrobbles for any artist, album or track on Last.fm at once.
by hankhank10 python
70
Display the playing Sonos track in real time on an e-ink display - also includes functionality for last.fm
by jac0b-w python
69 GPL-3.0
An app for Windows that will change your desktop wallpaper to the album art of the song you are listening to.
by JeffreyCA typescript
63 MIT
Display your recently played Spotify tracks on your GitHub profile README.
by lemonpaul python
62 MIT
Simple Python script that allow to import music from Yandex.Music to Spotify
by Chimildic javascript
54 MIT
Конструктор плейлистов Spotify
by Sh4dowSoul kotlin
43 Apache-2.0
Scrobble is a wip music tracking and browsing app. It uses the Lastf.fm and spotify APIs to deliver data. The whole UI is created using Jetpack compose.
by alii typescript
43 MIT
🎸 React Hook to use realtime last.fm data and display your currently played song in your application.
by aaronsgiles c++
41 BSD-3-Clause
BSD-licensed Yamaha FM sound cores (OPM, OPN, OPL, and others)
Top Authors in Lastfm
1
3 Libraries
88
2
3 Libraries
16
3
3 Libraries
206
4
3 Libraries
11
5
3 Libraries
8
6
3 Libraries
13
7
3 Libraries
152
8
2 Libraries
72
9
2 Libraries
7
10
2 Libraries
39
1
3 Libraries
88
2
3 Libraries
16
3
3 Libraries
206
4
3 Libraries
11
5
3 Libraries
8
6
3 Libraries
13
7
3 Libraries
152
8
2 Libraries
72
9
2 Libraries
7
10
2 Libraries
39
Trending Kits in Lastfm
No Trending Kits are available at this moment for Lastfm
Trending Discussions on Lastfm
Get Image out of a json response
Read JSON file to get highest resolution image (Last.FM)
System.Text.Json - Deserialize object that can be either an empty string or a class
How to check if music is playing with Last FM API
Finding Top-100 of a given year from a mysql table with last.fm scrobbles
How to code excel cells so that when you input data it automatically calculates what you enter + the previous cell
I need to map through json
Big text on the right side pushes to the image on the left side
Model associations problem: NoMethodError: undefined method `extensions' for #<Hash...>
How can I update a variable after render?
QUESTION
Get Image out of a json response
Asked 2021-Jul-05 at 07:59I'm making a discord.js bot that communicates with the last.fm API. I Want my bot to display the image from the request in an embed but it only gives me the result in different sizes.Everything else works perfectly fine i just need help with the image .Thank you a lot for your help:)
1axios
2 .get(request_url)
3 .then(res => {
4 if (res.data.message) {
5 message.channel.send('User not found')
6 return
7 }
8
9 const latest_track = res.data.recenttracks.track[0]
10
11 if (!latest_track) {
12 e.message.channel.send('User not found')
13 return
14 }
15
16 const {
17 name,
18 artist: { '#text': artist },
19 album: {'#text': album},
20 image: {'size': large, '#text' : image},
21 } = latest_track
22
23
24
25
26
27
28 const embed = new MessageEmbed()
29
30 .setColor('#0099ff')
31 .setTitle(`🎶now playing- ${fmname}`)
32 .setDescription(` **${name} - ${artist}** on ${album}`)
33 .setImage(image)
34
35 message.channel.send(embed)
36
This is the json response
1axios
2 .get(request_url)
3 .then(res => {
4 if (res.data.message) {
5 message.channel.send('User not found')
6 return
7 }
8
9 const latest_track = res.data.recenttracks.track[0]
10
11 if (!latest_track) {
12 e.message.channel.send('User not found')
13 return
14 }
15
16 const {
17 name,
18 artist: { '#text': artist },
19 album: {'#text': album},
20 image: {'size': large, '#text' : image},
21 } = latest_track
22
23
24
25
26
27
28 const embed = new MessageEmbed()
29
30 .setColor('#0099ff')
31 .setTitle(`🎶now playing- ${fmname}`)
32 .setDescription(` **${name} - ${artist}** on ${album}`)
33 .setImage(image)
34
35 message.channel.send(embed)
36 {
37 artist: { mbid: '', '#text': 'Tyler, The Creator' },
38 '@attr': { nowplaying: 'true' },
39 mbid: '',
40 album: { mbid: '', '#text': 'CALL ME IF YOU GET LOST' },
41 streamable: '0',
42 url: 'https://www.last.fm/music/Tyler,+The+Creator/_/SWEET+%2F+I+THOUGHT+YOU+WANTED+TO+DANCE+(feat.+Brent+Faiyaz+&+Fana+Hues)',
43 name: 'SWEET / I THOUGHT YOU WANTED TO DANCE (feat. Brent Faiyaz & Fana Hues)',
44 image: [
45 {
46 size: 'small',
47 '#text': 'https://lastfm.freetls.fastly.net/i/u/34s/8bed6cc4a2f68d3bb2228fbe6654b887.gif'
48 },
49 {
50 size: 'medium',
51 '#text': 'https://lastfm.freetls.fastly.net/i/u/64s/8bed6cc4a2f68d3bb2228fbe6654b887.gif'
52 },
53 {
54 size: 'large',
55 '#text': 'https://lastfm.freetls.fastly.net/i/u/174s/8bed6cc4a2f68d3bb2228fbe6654b887.gif'
56 },
57 {
58 size: 'extralarge',
59 '#text': 'https://lastfm.freetls.fastly.net/i/u/300x300/8bed6cc4a2f68d3bb2228fbe6654b887.gif'
60 }
61 ]
62 }
63
ANSWER
Answered 2021-Jul-05 at 07:59In the JSON response, you'll notice that you're given an Array of images. With each JSON object in the Array, there is a size and an image URL. If you wanted to access the "small" version of the image, you would ask for the first element in the Array. Computers start at 0 as opposed to one so you would do the following:
1axios
2 .get(request_url)
3 .then(res => {
4 if (res.data.message) {
5 message.channel.send('User not found')
6 return
7 }
8
9 const latest_track = res.data.recenttracks.track[0]
10
11 if (!latest_track) {
12 e.message.channel.send('User not found')
13 return
14 }
15
16 const {
17 name,
18 artist: { '#text': artist },
19 album: {'#text': album},
20 image: {'size': large, '#text' : image},
21 } = latest_track
22
23
24
25
26
27
28 const embed = new MessageEmbed()
29
30 .setColor('#0099ff')
31 .setTitle(`🎶now playing- ${fmname}`)
32 .setDescription(` **${name} - ${artist}** on ${album}`)
33 .setImage(image)
34
35 message.channel.send(embed)
36 {
37 artist: { mbid: '', '#text': 'Tyler, The Creator' },
38 '@attr': { nowplaying: 'true' },
39 mbid: '',
40 album: { mbid: '', '#text': 'CALL ME IF YOU GET LOST' },
41 streamable: '0',
42 url: 'https://www.last.fm/music/Tyler,+The+Creator/_/SWEET+%2F+I+THOUGHT+YOU+WANTED+TO+DANCE+(feat.+Brent+Faiyaz+&+Fana+Hues)',
43 name: 'SWEET / I THOUGHT YOU WANTED TO DANCE (feat. Brent Faiyaz & Fana Hues)',
44 image: [
45 {
46 size: 'small',
47 '#text': 'https://lastfm.freetls.fastly.net/i/u/34s/8bed6cc4a2f68d3bb2228fbe6654b887.gif'
48 },
49 {
50 size: 'medium',
51 '#text': 'https://lastfm.freetls.fastly.net/i/u/64s/8bed6cc4a2f68d3bb2228fbe6654b887.gif'
52 },
53 {
54 size: 'large',
55 '#text': 'https://lastfm.freetls.fastly.net/i/u/174s/8bed6cc4a2f68d3bb2228fbe6654b887.gif'
56 },
57 {
58 size: 'extralarge',
59 '#text': 'https://lastfm.freetls.fastly.net/i/u/300x300/8bed6cc4a2f68d3bb2228fbe6654b887.gif'
60 }
61 ]
62 }
63// Replace <JSON> with whatever variable represents your JSON
64.setImage(<JSON>.image[0]['#text'])
65
If you wanted medium, just replace 0 with 1. To learn more about Arrays, check out the Array article written by Mozilla.
Credit to @Elitezen as they pointed this out in the comments
QUESTION
Read JSON file to get highest resolution image (Last.FM)
Asked 2021-Jun-05 at 08:55So, I am working on a project that sends an Discord message every time it's a certain date, such as 'Mon 22:00:00'. The message includes my most listened album of that week. I got the code working that whenever I get the URL to get to the JSON, which included multiple links to images. Here is the JSON response I get:
1{
2 "album": {
3 "name": "Significant Other",
4 "artist": "Limp Bizkit",
5 "mbid": "be3e00aa-368a-3f09-ac96-cd094e9a7151",
6 "url": "https://www.last.fm/music/Limp+Bizkit/Significant+Other",
7 "image": [{
8 "#text": "https://lastfm.freetls.fastly.net/i/u/34s/1c00f7b9cd94c2b6fbd7f12fc00bd8d2.png",
9 "size": "small"
10 }, {
11 "#text": "https://lastfm.freetls.fastly.net/i/u/64s/1c00f7b9cd94c2b6fbd7f12fc00bd8d2.png",
12 "size": "medium"
13 }, {
14 "#text": "https://lastfm.freetls.fastly.net/i/u/174s/1c00f7b9cd94c2b6fbd7f12fc00bd8d2.png",
15 "size": "large"
16 }, {
17 "#text": "https://lastfm.freetls.fastly.net/i/u/300x300/1c00f7b9cd94c2b6fbd7f12fc00bd8d2.png",
18 "size": "extralarge"
19 }, {
20 "#text": "https://lastfm.freetls.fastly.net/i/u/300x300/1c00f7b9cd94c2b6fbd7f12fc00bd8d2.png",
21 "size": "mega"
22 }, {
23 "#text": "https://lastfm.freetls.fastly.net/i/u/300x300/1c00f7b9cd94c2b6fbd7f12fc00bd8d2.png",
24 "size": ""
25 }],
26 "listeners": "774409",
27 "playcount": "10274552",
28 "tracks": {
29 "track": [{
30 "name": "Intro",
31 "url": "https://www.last.fm/music/Limp+Bizkit/_/Intro",
32 "duration": "78",
33 "@attr": {
34 "rank": "1"
35 },
36 "streamable": {
37 "#text": "0",
38 "fulltrack": "0"
39 },
40 "artist": {
41 "name": "Limp Bizkit",
42 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
43 "url": "https://www.last.fm/music/Limp+Bizkit"
44 }
45 }, {
46 "name": "Just Like This",
47 "url": "https://www.last.fm/music/Limp+Bizkit/_/Just+Like+This",
48 "duration": "215",
49 "@attr": {
50 "rank": "2"
51 },
52 "streamable": {
53 "#text": "0",
54 "fulltrack": "0"
55 },
56 "artist": {
57 "name": "Limp Bizkit",
58 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
59 "url": "https://www.last.fm/music/Limp+Bizkit"
60 }
61 }, {
62 "name": "Nookie",
63 "url": "https://www.last.fm/music/Limp+Bizkit/_/Nookie",
64 "duration": "289",
65 "@attr": {
66 "rank": "3"
67 },
68 "streamable": {
69 "#text": "0",
70 "fulltrack": "0"
71 },
72 "artist": {
73 "name": "Limp Bizkit",
74 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
75 "url": "https://www.last.fm/music/Limp+Bizkit"
76 }
77 }, {
78 "name": "Break Stuff",
79 "url": "https://www.last.fm/music/Limp+Bizkit/_/Break+Stuff",
80 "duration": "166",
81 "@attr": {
82 "rank": "4"
83 },
84 "streamable": {
85 "#text": "0",
86 "fulltrack": "0"
87 },
88 "artist": {
89 "name": "Limp Bizkit",
90 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
91 "url": "https://www.last.fm/music/Limp+Bizkit"
92 }
93 }, {
94 "name": "Re-Arranged",
95 "url": "https://www.last.fm/music/Limp+Bizkit/_/Re-Arranged",
96 "duration": "354",
97 "@attr": {
98 "rank": "5"
99 },
100 "streamable": {
101 "#text": "0",
102 "fulltrack": "0"
103 },
104 "artist": {
105 "name": "Limp Bizkit",
106 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
107 "url": "https://www.last.fm/music/Limp+Bizkit"
108 }
109 }, {
110 "name": "I'm Broke",
111 "url": "https://www.last.fm/music/Limp+Bizkit/_/I%27m+Broke",
112 "duration": "239",
113 "@attr": {
114 "rank": "6"
115 },
116 "streamable": {
117 "#text": "0",
118 "fulltrack": "0"
119 },
120 "artist": {
121 "name": "Limp Bizkit",
122 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
123 "url": "https://www.last.fm/music/Limp+Bizkit"
124 }
125 }, {
126 "name": "Nobody Like You",
127 "url": "https://www.last.fm/music/Limp+Bizkit/_/Nobody+Like+You",
128 "duration": "260",
129 "@attr": {
130 "rank": "7"
131 },
132 "streamable": {
133 "#text": "0",
134 "fulltrack": "0"
135 },
136 "artist": {
137 "name": "Limp Bizkit",
138 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
139 "url": "https://www.last.fm/music/Limp+Bizkit"
140 }
141 }, {
142 "name": "Don't Go Off Wandering",
143 "url": "https://www.last.fm/music/Limp+Bizkit/_/Don%27t+Go+Off+Wandering",
144 "duration": "239",
145 "@attr": {
146 "rank": "8"
147 },
148 "streamable": {
149 "#text": "0",
150 "fulltrack": "0"
151 },
152 "artist": {
153 "name": "Limp Bizkit",
154 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
155 "url": "https://www.last.fm/music/Limp+Bizkit"
156 }
157 }, {
158 "name": "9 Teen 90 Nine",
159 "url": "https://www.last.fm/music/Limp+Bizkit/_/9+Teen+90+Nine",
160 "duration": "276",
161 "@attr": {
162 "rank": "9"
163 },
164 "streamable": {
165 "#text": "0",
166 "fulltrack": "0"
167 },
168 "artist": {
169 "name": "Limp Bizkit",
170 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
171 "url": "https://www.last.fm/music/Limp+Bizkit"
172 }
173 }, {
174 "name": "N 2 Gether Now",
175 "url": "https://www.last.fm/music/Limp+Bizkit/_/N+2+Gether+Now",
176 "duration": "289",
177 "@attr": {
178 "rank": "10"
179 },
180 "streamable": {
181 "#text": "0",
182 "fulltrack": "0"
183 },
184 "artist": {
185 "name": "Limp Bizkit",
186 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
187 "url": "https://www.last.fm/music/Limp+Bizkit"
188 }
189 }, {
190 "name": "Trust?",
191 "url": "https://www.last.fm/music/Limp+Bizkit/_/Trust%3F",
192 "duration": "299",
193 "@attr": {
194 "rank": "11"
195 },
196 "streamable": {
197 "#text": "0",
198 "fulltrack": "0"
199 },
200 "artist": {
201 "name": "Limp Bizkit",
202 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
203 "url": "https://www.last.fm/music/Limp+Bizkit"
204 }
205 }, {
206 "name": "No Sex",
207 "url": "https://www.last.fm/music/Limp+Bizkit/_/No+Sex",
208 "duration": "234",
209 "@attr": {
210 "rank": "12"
211 },
212 "streamable": {
213 "#text": "0",
214 "fulltrack": "0"
215 },
216 "artist": {
217 "name": "Limp Bizkit",
218 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
219 "url": "https://www.last.fm/music/Limp+Bizkit"
220 }
221 }, {
222 "name": "Show Me What You Got",
223 "url": "https://www.last.fm/music/Limp+Bizkit/_/Show+Me+What+You+Got",
224 "duration": "266",
225 "@attr": {
226 "rank": "13"
227 },
228 "streamable": {
229 "#text": "0",
230 "fulltrack": "0"
231 },
232 "artist": {
233 "name": "Limp Bizkit",
234 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
235 "url": "https://www.last.fm/music/Limp+Bizkit"
236 }
237 }, {
238 "name": "A Lesson Learned",
239 "url": "https://www.last.fm/music/Limp+Bizkit/_/A+Lesson+Learned",
240 "duration": "160",
241 "@attr": {
242 "rank": "14"
243 },
244 "streamable": {
245 "#text": "0",
246 "fulltrack": "0"
247 },
248 "artist": {
249 "name": "Limp Bizkit",
250 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
251 "url": "https://www.last.fm/music/Limp+Bizkit"
252 }
253 }, {
254 "name": "Outro / Radio Sucks / The Mind of Les",
255 "url": "https://www.last.fm/music/Limp+Bizkit/_/Outro+%2F+Radio+Sucks+%2F+The+Mind+of+Les",
256 "duration": "438",
257 "@attr": {
258 "rank": "15"
259 },
260 "streamable": {
261 "#text": "0",
262 "fulltrack": "0"
263 },
264 "artist": {
265 "name": "Limp Bizkit",
266 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
267 "url": "https://www.last.fm/music/Limp+Bizkit"
268 }
269 }, {
270 "name": "[silence]",
271 "url": "https://www.last.fm/music/Limp+Bizkit/_/%5Bsilence%5D",
272 "duration": "4",
273 "@attr": {
274 "rank": "16"
275 },
276 "streamable": {
277 "#text": "0",
278 "fulltrack": "0"
279 },
280 "artist": {
281 "name": "Limp Bizkit",
282 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
283 "url": "https://www.last.fm/music/Limp+Bizkit"
284 }
285 }]
286 },
287 "tags": {
288 "tag": [{
289 "name": "albums I own",
290 "url": "https://www.last.fm/tag/albums+I+own"
291 }, {
292 "name": "Nu Metal",
293 "url": "https://www.last.fm/tag/Nu+Metal"
294 }, {
295 "name": "rapcore",
296 "url": "https://www.last.fm/tag/rapcore"
297 }, {
298 "name": "rock",
299 "url": "https://www.last.fm/tag/rock"
300 }, {
301 "name": "limp bizkit",
302 "url": "https://www.last.fm/tag/limp+bizkit"
303 }]
304 },
305 "wiki": {
306 "published": "11 Jul 2016, 20:19",
307 "summary": "Significant Other is the second album by American rap rock/nu metal band Limp Bizkit. Released in 1999 by Flip/Interscope Records, the album saw the band expanding its sound from that of its debut album Three Dollar Bill, Yall, to incorporate further metal and hip hop influences. Significant Other was co-produced by Terry Date and Limp Bizkit. The album has sold at least 16 million copies worldwide. <a href=\"http://www.last.fm/music/Limp+Bizkit/Significant+Other\">Read more on Last.fm</a>.",
308 "content": "Significant Other is the second album by American rap rock/nu metal band Limp Bizkit. Released in 1999 by Flip/Interscope Records, the album saw the band expanding its sound from that of its debut album Three Dollar Bill, Yall, to incorporate further metal and hip hop influences. Significant Other was co-produced by Terry Date and Limp Bizkit. The album has sold at least 16 million copies worldwide. <a href=\"http://www.last.fm/music/Limp+Bizkit/Significant+Other\">Read more on Last.fm</a>. User-contributed text is available under the Creative Commons By-SA License; additional terms may apply."
309 }
310 }
311}
312
I want to get the link that is above "size": ""
, as this image has the highest resolution. How do I get to this? I use Python to make the Discord bot, so if you could explain in Python language, that would be great! Thanks in advance!
ANSWER
Answered 2021-Jun-05 at 08:55To convert the JSON string into Python objects you can use:
1{
2 "album": {
3 "name": "Significant Other",
4 "artist": "Limp Bizkit",
5 "mbid": "be3e00aa-368a-3f09-ac96-cd094e9a7151",
6 "url": "https://www.last.fm/music/Limp+Bizkit/Significant+Other",
7 "image": [{
8 "#text": "https://lastfm.freetls.fastly.net/i/u/34s/1c00f7b9cd94c2b6fbd7f12fc00bd8d2.png",
9 "size": "small"
10 }, {
11 "#text": "https://lastfm.freetls.fastly.net/i/u/64s/1c00f7b9cd94c2b6fbd7f12fc00bd8d2.png",
12 "size": "medium"
13 }, {
14 "#text": "https://lastfm.freetls.fastly.net/i/u/174s/1c00f7b9cd94c2b6fbd7f12fc00bd8d2.png",
15 "size": "large"
16 }, {
17 "#text": "https://lastfm.freetls.fastly.net/i/u/300x300/1c00f7b9cd94c2b6fbd7f12fc00bd8d2.png",
18 "size": "extralarge"
19 }, {
20 "#text": "https://lastfm.freetls.fastly.net/i/u/300x300/1c00f7b9cd94c2b6fbd7f12fc00bd8d2.png",
21 "size": "mega"
22 }, {
23 "#text": "https://lastfm.freetls.fastly.net/i/u/300x300/1c00f7b9cd94c2b6fbd7f12fc00bd8d2.png",
24 "size": ""
25 }],
26 "listeners": "774409",
27 "playcount": "10274552",
28 "tracks": {
29 "track": [{
30 "name": "Intro",
31 "url": "https://www.last.fm/music/Limp+Bizkit/_/Intro",
32 "duration": "78",
33 "@attr": {
34 "rank": "1"
35 },
36 "streamable": {
37 "#text": "0",
38 "fulltrack": "0"
39 },
40 "artist": {
41 "name": "Limp Bizkit",
42 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
43 "url": "https://www.last.fm/music/Limp+Bizkit"
44 }
45 }, {
46 "name": "Just Like This",
47 "url": "https://www.last.fm/music/Limp+Bizkit/_/Just+Like+This",
48 "duration": "215",
49 "@attr": {
50 "rank": "2"
51 },
52 "streamable": {
53 "#text": "0",
54 "fulltrack": "0"
55 },
56 "artist": {
57 "name": "Limp Bizkit",
58 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
59 "url": "https://www.last.fm/music/Limp+Bizkit"
60 }
61 }, {
62 "name": "Nookie",
63 "url": "https://www.last.fm/music/Limp+Bizkit/_/Nookie",
64 "duration": "289",
65 "@attr": {
66 "rank": "3"
67 },
68 "streamable": {
69 "#text": "0",
70 "fulltrack": "0"
71 },
72 "artist": {
73 "name": "Limp Bizkit",
74 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
75 "url": "https://www.last.fm/music/Limp+Bizkit"
76 }
77 }, {
78 "name": "Break Stuff",
79 "url": "https://www.last.fm/music/Limp+Bizkit/_/Break+Stuff",
80 "duration": "166",
81 "@attr": {
82 "rank": "4"
83 },
84 "streamable": {
85 "#text": "0",
86 "fulltrack": "0"
87 },
88 "artist": {
89 "name": "Limp Bizkit",
90 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
91 "url": "https://www.last.fm/music/Limp+Bizkit"
92 }
93 }, {
94 "name": "Re-Arranged",
95 "url": "https://www.last.fm/music/Limp+Bizkit/_/Re-Arranged",
96 "duration": "354",
97 "@attr": {
98 "rank": "5"
99 },
100 "streamable": {
101 "#text": "0",
102 "fulltrack": "0"
103 },
104 "artist": {
105 "name": "Limp Bizkit",
106 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
107 "url": "https://www.last.fm/music/Limp+Bizkit"
108 }
109 }, {
110 "name": "I'm Broke",
111 "url": "https://www.last.fm/music/Limp+Bizkit/_/I%27m+Broke",
112 "duration": "239",
113 "@attr": {
114 "rank": "6"
115 },
116 "streamable": {
117 "#text": "0",
118 "fulltrack": "0"
119 },
120 "artist": {
121 "name": "Limp Bizkit",
122 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
123 "url": "https://www.last.fm/music/Limp+Bizkit"
124 }
125 }, {
126 "name": "Nobody Like You",
127 "url": "https://www.last.fm/music/Limp+Bizkit/_/Nobody+Like+You",
128 "duration": "260",
129 "@attr": {
130 "rank": "7"
131 },
132 "streamable": {
133 "#text": "0",
134 "fulltrack": "0"
135 },
136 "artist": {
137 "name": "Limp Bizkit",
138 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
139 "url": "https://www.last.fm/music/Limp+Bizkit"
140 }
141 }, {
142 "name": "Don't Go Off Wandering",
143 "url": "https://www.last.fm/music/Limp+Bizkit/_/Don%27t+Go+Off+Wandering",
144 "duration": "239",
145 "@attr": {
146 "rank": "8"
147 },
148 "streamable": {
149 "#text": "0",
150 "fulltrack": "0"
151 },
152 "artist": {
153 "name": "Limp Bizkit",
154 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
155 "url": "https://www.last.fm/music/Limp+Bizkit"
156 }
157 }, {
158 "name": "9 Teen 90 Nine",
159 "url": "https://www.last.fm/music/Limp+Bizkit/_/9+Teen+90+Nine",
160 "duration": "276",
161 "@attr": {
162 "rank": "9"
163 },
164 "streamable": {
165 "#text": "0",
166 "fulltrack": "0"
167 },
168 "artist": {
169 "name": "Limp Bizkit",
170 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
171 "url": "https://www.last.fm/music/Limp+Bizkit"
172 }
173 }, {
174 "name": "N 2 Gether Now",
175 "url": "https://www.last.fm/music/Limp+Bizkit/_/N+2+Gether+Now",
176 "duration": "289",
177 "@attr": {
178 "rank": "10"
179 },
180 "streamable": {
181 "#text": "0",
182 "fulltrack": "0"
183 },
184 "artist": {
185 "name": "Limp Bizkit",
186 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
187 "url": "https://www.last.fm/music/Limp+Bizkit"
188 }
189 }, {
190 "name": "Trust?",
191 "url": "https://www.last.fm/music/Limp+Bizkit/_/Trust%3F",
192 "duration": "299",
193 "@attr": {
194 "rank": "11"
195 },
196 "streamable": {
197 "#text": "0",
198 "fulltrack": "0"
199 },
200 "artist": {
201 "name": "Limp Bizkit",
202 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
203 "url": "https://www.last.fm/music/Limp+Bizkit"
204 }
205 }, {
206 "name": "No Sex",
207 "url": "https://www.last.fm/music/Limp+Bizkit/_/No+Sex",
208 "duration": "234",
209 "@attr": {
210 "rank": "12"
211 },
212 "streamable": {
213 "#text": "0",
214 "fulltrack": "0"
215 },
216 "artist": {
217 "name": "Limp Bizkit",
218 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
219 "url": "https://www.last.fm/music/Limp+Bizkit"
220 }
221 }, {
222 "name": "Show Me What You Got",
223 "url": "https://www.last.fm/music/Limp+Bizkit/_/Show+Me+What+You+Got",
224 "duration": "266",
225 "@attr": {
226 "rank": "13"
227 },
228 "streamable": {
229 "#text": "0",
230 "fulltrack": "0"
231 },
232 "artist": {
233 "name": "Limp Bizkit",
234 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
235 "url": "https://www.last.fm/music/Limp+Bizkit"
236 }
237 }, {
238 "name": "A Lesson Learned",
239 "url": "https://www.last.fm/music/Limp+Bizkit/_/A+Lesson+Learned",
240 "duration": "160",
241 "@attr": {
242 "rank": "14"
243 },
244 "streamable": {
245 "#text": "0",
246 "fulltrack": "0"
247 },
248 "artist": {
249 "name": "Limp Bizkit",
250 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
251 "url": "https://www.last.fm/music/Limp+Bizkit"
252 }
253 }, {
254 "name": "Outro / Radio Sucks / The Mind of Les",
255 "url": "https://www.last.fm/music/Limp+Bizkit/_/Outro+%2F+Radio+Sucks+%2F+The+Mind+of+Les",
256 "duration": "438",
257 "@attr": {
258 "rank": "15"
259 },
260 "streamable": {
261 "#text": "0",
262 "fulltrack": "0"
263 },
264 "artist": {
265 "name": "Limp Bizkit",
266 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
267 "url": "https://www.last.fm/music/Limp+Bizkit"
268 }
269 }, {
270 "name": "[silence]",
271 "url": "https://www.last.fm/music/Limp+Bizkit/_/%5Bsilence%5D",
272 "duration": "4",
273 "@attr": {
274 "rank": "16"
275 },
276 "streamable": {
277 "#text": "0",
278 "fulltrack": "0"
279 },
280 "artist": {
281 "name": "Limp Bizkit",
282 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
283 "url": "https://www.last.fm/music/Limp+Bizkit"
284 }
285 }]
286 },
287 "tags": {
288 "tag": [{
289 "name": "albums I own",
290 "url": "https://www.last.fm/tag/albums+I+own"
291 }, {
292 "name": "Nu Metal",
293 "url": "https://www.last.fm/tag/Nu+Metal"
294 }, {
295 "name": "rapcore",
296 "url": "https://www.last.fm/tag/rapcore"
297 }, {
298 "name": "rock",
299 "url": "https://www.last.fm/tag/rock"
300 }, {
301 "name": "limp bizkit",
302 "url": "https://www.last.fm/tag/limp+bizkit"
303 }]
304 },
305 "wiki": {
306 "published": "11 Jul 2016, 20:19",
307 "summary": "Significant Other is the second album by American rap rock/nu metal band Limp Bizkit. Released in 1999 by Flip/Interscope Records, the album saw the band expanding its sound from that of its debut album Three Dollar Bill, Yall, to incorporate further metal and hip hop influences. Significant Other was co-produced by Terry Date and Limp Bizkit. The album has sold at least 16 million copies worldwide. <a href=\"http://www.last.fm/music/Limp+Bizkit/Significant+Other\">Read more on Last.fm</a>.",
308 "content": "Significant Other is the second album by American rap rock/nu metal band Limp Bizkit. Released in 1999 by Flip/Interscope Records, the album saw the band expanding its sound from that of its debut album Three Dollar Bill, Yall, to incorporate further metal and hip hop influences. Significant Other was co-produced by Terry Date and Limp Bizkit. The album has sold at least 16 million copies worldwide. <a href=\"http://www.last.fm/music/Limp+Bizkit/Significant+Other\">Read more on Last.fm</a>. User-contributed text is available under the Creative Commons By-SA License; additional terms may apply."
309 }
310 }
311}
312import json
313album_data = json.loads(album_json_string)
314
To extract the 'mega' image URL, you can iterate through the images list with a list comprehension:
1{
2 "album": {
3 "name": "Significant Other",
4 "artist": "Limp Bizkit",
5 "mbid": "be3e00aa-368a-3f09-ac96-cd094e9a7151",
6 "url": "https://www.last.fm/music/Limp+Bizkit/Significant+Other",
7 "image": [{
8 "#text": "https://lastfm.freetls.fastly.net/i/u/34s/1c00f7b9cd94c2b6fbd7f12fc00bd8d2.png",
9 "size": "small"
10 }, {
11 "#text": "https://lastfm.freetls.fastly.net/i/u/64s/1c00f7b9cd94c2b6fbd7f12fc00bd8d2.png",
12 "size": "medium"
13 }, {
14 "#text": "https://lastfm.freetls.fastly.net/i/u/174s/1c00f7b9cd94c2b6fbd7f12fc00bd8d2.png",
15 "size": "large"
16 }, {
17 "#text": "https://lastfm.freetls.fastly.net/i/u/300x300/1c00f7b9cd94c2b6fbd7f12fc00bd8d2.png",
18 "size": "extralarge"
19 }, {
20 "#text": "https://lastfm.freetls.fastly.net/i/u/300x300/1c00f7b9cd94c2b6fbd7f12fc00bd8d2.png",
21 "size": "mega"
22 }, {
23 "#text": "https://lastfm.freetls.fastly.net/i/u/300x300/1c00f7b9cd94c2b6fbd7f12fc00bd8d2.png",
24 "size": ""
25 }],
26 "listeners": "774409",
27 "playcount": "10274552",
28 "tracks": {
29 "track": [{
30 "name": "Intro",
31 "url": "https://www.last.fm/music/Limp+Bizkit/_/Intro",
32 "duration": "78",
33 "@attr": {
34 "rank": "1"
35 },
36 "streamable": {
37 "#text": "0",
38 "fulltrack": "0"
39 },
40 "artist": {
41 "name": "Limp Bizkit",
42 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
43 "url": "https://www.last.fm/music/Limp+Bizkit"
44 }
45 }, {
46 "name": "Just Like This",
47 "url": "https://www.last.fm/music/Limp+Bizkit/_/Just+Like+This",
48 "duration": "215",
49 "@attr": {
50 "rank": "2"
51 },
52 "streamable": {
53 "#text": "0",
54 "fulltrack": "0"
55 },
56 "artist": {
57 "name": "Limp Bizkit",
58 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
59 "url": "https://www.last.fm/music/Limp+Bizkit"
60 }
61 }, {
62 "name": "Nookie",
63 "url": "https://www.last.fm/music/Limp+Bizkit/_/Nookie",
64 "duration": "289",
65 "@attr": {
66 "rank": "3"
67 },
68 "streamable": {
69 "#text": "0",
70 "fulltrack": "0"
71 },
72 "artist": {
73 "name": "Limp Bizkit",
74 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
75 "url": "https://www.last.fm/music/Limp+Bizkit"
76 }
77 }, {
78 "name": "Break Stuff",
79 "url": "https://www.last.fm/music/Limp+Bizkit/_/Break+Stuff",
80 "duration": "166",
81 "@attr": {
82 "rank": "4"
83 },
84 "streamable": {
85 "#text": "0",
86 "fulltrack": "0"
87 },
88 "artist": {
89 "name": "Limp Bizkit",
90 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
91 "url": "https://www.last.fm/music/Limp+Bizkit"
92 }
93 }, {
94 "name": "Re-Arranged",
95 "url": "https://www.last.fm/music/Limp+Bizkit/_/Re-Arranged",
96 "duration": "354",
97 "@attr": {
98 "rank": "5"
99 },
100 "streamable": {
101 "#text": "0",
102 "fulltrack": "0"
103 },
104 "artist": {
105 "name": "Limp Bizkit",
106 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
107 "url": "https://www.last.fm/music/Limp+Bizkit"
108 }
109 }, {
110 "name": "I'm Broke",
111 "url": "https://www.last.fm/music/Limp+Bizkit/_/I%27m+Broke",
112 "duration": "239",
113 "@attr": {
114 "rank": "6"
115 },
116 "streamable": {
117 "#text": "0",
118 "fulltrack": "0"
119 },
120 "artist": {
121 "name": "Limp Bizkit",
122 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
123 "url": "https://www.last.fm/music/Limp+Bizkit"
124 }
125 }, {
126 "name": "Nobody Like You",
127 "url": "https://www.last.fm/music/Limp+Bizkit/_/Nobody+Like+You",
128 "duration": "260",
129 "@attr": {
130 "rank": "7"
131 },
132 "streamable": {
133 "#text": "0",
134 "fulltrack": "0"
135 },
136 "artist": {
137 "name": "Limp Bizkit",
138 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
139 "url": "https://www.last.fm/music/Limp+Bizkit"
140 }
141 }, {
142 "name": "Don't Go Off Wandering",
143 "url": "https://www.last.fm/music/Limp+Bizkit/_/Don%27t+Go+Off+Wandering",
144 "duration": "239",
145 "@attr": {
146 "rank": "8"
147 },
148 "streamable": {
149 "#text": "0",
150 "fulltrack": "0"
151 },
152 "artist": {
153 "name": "Limp Bizkit",
154 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
155 "url": "https://www.last.fm/music/Limp+Bizkit"
156 }
157 }, {
158 "name": "9 Teen 90 Nine",
159 "url": "https://www.last.fm/music/Limp+Bizkit/_/9+Teen+90+Nine",
160 "duration": "276",
161 "@attr": {
162 "rank": "9"
163 },
164 "streamable": {
165 "#text": "0",
166 "fulltrack": "0"
167 },
168 "artist": {
169 "name": "Limp Bizkit",
170 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
171 "url": "https://www.last.fm/music/Limp+Bizkit"
172 }
173 }, {
174 "name": "N 2 Gether Now",
175 "url": "https://www.last.fm/music/Limp+Bizkit/_/N+2+Gether+Now",
176 "duration": "289",
177 "@attr": {
178 "rank": "10"
179 },
180 "streamable": {
181 "#text": "0",
182 "fulltrack": "0"
183 },
184 "artist": {
185 "name": "Limp Bizkit",
186 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
187 "url": "https://www.last.fm/music/Limp+Bizkit"
188 }
189 }, {
190 "name": "Trust?",
191 "url": "https://www.last.fm/music/Limp+Bizkit/_/Trust%3F",
192 "duration": "299",
193 "@attr": {
194 "rank": "11"
195 },
196 "streamable": {
197 "#text": "0",
198 "fulltrack": "0"
199 },
200 "artist": {
201 "name": "Limp Bizkit",
202 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
203 "url": "https://www.last.fm/music/Limp+Bizkit"
204 }
205 }, {
206 "name": "No Sex",
207 "url": "https://www.last.fm/music/Limp+Bizkit/_/No+Sex",
208 "duration": "234",
209 "@attr": {
210 "rank": "12"
211 },
212 "streamable": {
213 "#text": "0",
214 "fulltrack": "0"
215 },
216 "artist": {
217 "name": "Limp Bizkit",
218 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
219 "url": "https://www.last.fm/music/Limp+Bizkit"
220 }
221 }, {
222 "name": "Show Me What You Got",
223 "url": "https://www.last.fm/music/Limp+Bizkit/_/Show+Me+What+You+Got",
224 "duration": "266",
225 "@attr": {
226 "rank": "13"
227 },
228 "streamable": {
229 "#text": "0",
230 "fulltrack": "0"
231 },
232 "artist": {
233 "name": "Limp Bizkit",
234 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
235 "url": "https://www.last.fm/music/Limp+Bizkit"
236 }
237 }, {
238 "name": "A Lesson Learned",
239 "url": "https://www.last.fm/music/Limp+Bizkit/_/A+Lesson+Learned",
240 "duration": "160",
241 "@attr": {
242 "rank": "14"
243 },
244 "streamable": {
245 "#text": "0",
246 "fulltrack": "0"
247 },
248 "artist": {
249 "name": "Limp Bizkit",
250 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
251 "url": "https://www.last.fm/music/Limp+Bizkit"
252 }
253 }, {
254 "name": "Outro / Radio Sucks / The Mind of Les",
255 "url": "https://www.last.fm/music/Limp+Bizkit/_/Outro+%2F+Radio+Sucks+%2F+The+Mind+of+Les",
256 "duration": "438",
257 "@attr": {
258 "rank": "15"
259 },
260 "streamable": {
261 "#text": "0",
262 "fulltrack": "0"
263 },
264 "artist": {
265 "name": "Limp Bizkit",
266 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
267 "url": "https://www.last.fm/music/Limp+Bizkit"
268 }
269 }, {
270 "name": "[silence]",
271 "url": "https://www.last.fm/music/Limp+Bizkit/_/%5Bsilence%5D",
272 "duration": "4",
273 "@attr": {
274 "rank": "16"
275 },
276 "streamable": {
277 "#text": "0",
278 "fulltrack": "0"
279 },
280 "artist": {
281 "name": "Limp Bizkit",
282 "mbid": "8f9d6bb2-dba4-4cca-9967-cc02b9f4820c",
283 "url": "https://www.last.fm/music/Limp+Bizkit"
284 }
285 }]
286 },
287 "tags": {
288 "tag": [{
289 "name": "albums I own",
290 "url": "https://www.last.fm/tag/albums+I+own"
291 }, {
292 "name": "Nu Metal",
293 "url": "https://www.last.fm/tag/Nu+Metal"
294 }, {
295 "name": "rapcore",
296 "url": "https://www.last.fm/tag/rapcore"
297 }, {
298 "name": "rock",
299 "url": "https://www.last.fm/tag/rock"
300 }, {
301 "name": "limp bizkit",
302 "url": "https://www.last.fm/tag/limp+bizkit"
303 }]
304 },
305 "wiki": {
306 "published": "11 Jul 2016, 20:19",
307 "summary": "Significant Other is the second album by American rap rock/nu metal band Limp Bizkit. Released in 1999 by Flip/Interscope Records, the album saw the band expanding its sound from that of its debut album Three Dollar Bill, Yall, to incorporate further metal and hip hop influences. Significant Other was co-produced by Terry Date and Limp Bizkit. The album has sold at least 16 million copies worldwide. <a href=\"http://www.last.fm/music/Limp+Bizkit/Significant+Other\">Read more on Last.fm</a>.",
308 "content": "Significant Other is the second album by American rap rock/nu metal band Limp Bizkit. Released in 1999 by Flip/Interscope Records, the album saw the band expanding its sound from that of its debut album Three Dollar Bill, Yall, to incorporate further metal and hip hop influences. Significant Other was co-produced by Terry Date and Limp Bizkit. The album has sold at least 16 million copies worldwide. <a href=\"http://www.last.fm/music/Limp+Bizkit/Significant+Other\">Read more on Last.fm</a>. User-contributed text is available under the Creative Commons By-SA License; additional terms may apply."
309 }
310 }
311}
312import json
313album_data = json.loads(album_json_string)
314images = album_data['album']['image']
315mega_images = [i for i in images if i['size'] == 'mega']
316try:
317 mega_image_url = mega_images[0]['image']
318except IndexError:
319 #do something if the mega URL isn't present
320
QUESTION
System.Text.Json - Deserialize object that can be either an empty string or a class
Asked 2021-May-19 at 13:41I'm using System.Text.Json
to deserialize some json. (More specifically, this call from the Last.fm API in json format)
The json that I'm trying to deserialize has a quite unconventional way of handling null values for some objects, for example when its null I get this:
1 "tags": "",
2
And like this when it has values:
1 "tags": "",
2 "tags": {
3 "tag": [
4 {
5 "name": "classic rock",
6 "url": "https://www.last.fm/tag/classic+rock"
7 },
8 {
9 "name": "rock",
10 "url": "https://www.last.fm/tag/rock"
11 }
12 ]
13 }
14
My C# class looks like this:
1 "tags": "",
2 "tags": {
3 "tag": [
4 {
5 "name": "classic rock",
6 "url": "https://www.last.fm/tag/classic+rock"
7 },
8 {
9 "name": "rock",
10 "url": "https://www.last.fm/tag/rock"
11 }
12 ]
13 }
14public class Artist
15{
16 public Tags Tags { get; set; }
17}
18
19public class Tags
20{
21 public Tag[] Tag { get; set; }
22}
23
24public class Tag
25{
26 public string Name { get; set; }
27 public string Url { get; set; }
28}
29
How would I check if an object is an empty string before actually trying to deserialize it?
When I try to deserialize it:
1 "tags": "",
2 "tags": {
3 "tag": [
4 {
5 "name": "classic rock",
6 "url": "https://www.last.fm/tag/classic+rock"
7 },
8 {
9 "name": "rock",
10 "url": "https://www.last.fm/tag/rock"
11 }
12 ]
13 }
14public class Artist
15{
16 public Tags Tags { get; set; }
17}
18
19public class Tags
20{
21 public Tag[] Tag { get; set; }
22}
23
24public class Tag
25{
26 public string Name { get; set; }
27 public string Url { get; set; }
28}
29var deserializedObject = JsonSerializer.Deserialize<T>(requestBody);
30
It throws a System.Text.Json.JsonException: The JSON value could not be converted to FMBot.LastFM.Domain.Models.Tags. Path: $.artist.tags
error.
This call used to work when the value was actually null
, but now that it's an empty string it is broken and I can't figure out a solution.
ANSWER
Answered 2021-May-19 at 12:56One simple way to solve this is by changing the type of the Tags
property to dynamic
.
1 "tags": "",
2 "tags": {
3 "tag": [
4 {
5 "name": "classic rock",
6 "url": "https://www.last.fm/tag/classic+rock"
7 },
8 {
9 "name": "rock",
10 "url": "https://www.last.fm/tag/rock"
11 }
12 ]
13 }
14public class Artist
15{
16 public Tags Tags { get; set; }
17}
18
19public class Tags
20{
21 public Tag[] Tag { get; set; }
22}
23
24public class Tag
25{
26 public string Name { get; set; }
27 public string Url { get; set; }
28}
29var deserializedObject = JsonSerializer.Deserialize<T>(requestBody);
30public class Artist
31{
32 public dynamic Tags { get; set; }
33}
34
You can then check if Tags is Tag[]
or Tags is string
and act accordingly. Don't forget to also check if it is neither of the above (and possibly throw).
QUESTION
How to check if music is playing with Last FM API
Asked 2021-Apr-27 at 11:28I'm doing a React app where I'm using Last FM API. App shows current track if music is playing or if it's not it shows last listened track. At this point everything works just fine. My problem is I want to show if I'm currently listening or not, but just don't know how. I tried to scroll through documentation but didn't really find anything helpful.
I'm fetching data from here: https://ws.audioscrobbler.com/2.0/?method=user.getRecentTracks&user=${userName}&api_key=${apiKey}&format=json
1const track = scrobbles?.recenttracks?.track;
2
3const [
4 { name: songName, artist: { '#text': artistName } = {}}
5= {}] = track;
6
7 return (
8 <div>
9 <h1>playing</h1>
10 <h3>{songName}</h3>
11 <h3>{artistName}</h3>
12 </div>
13 )
14
scrobbles is variable where all of JSON data is stored. In JSON data there is nowplaying attribute inside track array which returns boolean value, I just don't know how to use that value.
I found this link which shows stored JSON data: https://lastfm-docs.github.io/api-docs/user/getRecentTracks/
I'd like to have probably some kind of conditional statement around that h1 element which shows playing or not playing.
Any ideas how to do that? Thanks
ANSWER
Answered 2021-Apr-26 at 22:12The track that’s currently playing should have a
1const track = scrobbles?.recenttracks?.track;
2
3const [
4 { name: songName, artist: { '#text': artistName } = {}}
5= {}] = track;
6
7 return (
8 <div>
9 <h1>playing</h1>
10 <h3>{songName}</h3>
11 <h3>{artistName}</h3>
12 </div>
13 )
14"@attr": {
15 "nowplaying": "true"
16},
17
attribute associated with it. Compare the sample output of getRecentTracks
for scenarios when a track is currently scrobbling vs. when it’s not.
I’m not sure why “true” is a string, not a Boolean.
QUESTION
Finding Top-100 of a given year from a mysql table with last.fm scrobbles
Asked 2020-Dec-07 at 23:22I imported to a MariaDB table a CSV file generated by this tool with all my last.fm scrobbles, the CREATE script is the following:
1CREATE TABLE `scrobbles` (
2 `id` INT(11) NOT NULL AUTO_INCREMENT,
3 `artist` VARCHAR(128) NULL DEFAULT '',
4 `album` VARCHAR(128) NULL DEFAULT '',
5 `title` VARCHAR(128) NULL DEFAULT '',
6 `datahora` DATETIME NULL DEFAULT current_timestamp(),
7 PRIMARY KEY (`id`)
8)ENGINE=InnoDB;
9
I want to know how can i get the most executed tracks (basically the title+artist combo most repeating) of a given year, ordered by the number of plays/scrobbles of each track.
ANSWER
Answered 2020-Dec-07 at 23:17If you want this for a single year, you can aggregate, sort and limit:
1CREATE TABLE `scrobbles` (
2 `id` INT(11) NOT NULL AUTO_INCREMENT,
3 `artist` VARCHAR(128) NULL DEFAULT '',
4 `album` VARCHAR(128) NULL DEFAULT '',
5 `title` VARCHAR(128) NULL DEFAULT '',
6 `datahora` DATETIME NULL DEFAULT current_timestamp(),
7 PRIMARY KEY (`id`)
8)ENGINE=InnoDB;
9select artist, album, title, count(*) cnt
10from scrobbles
11where datahora >= '2019-01-01' and datahora < '2020-01-01'
12group by artist, album, title
13order by count(*) desc limit 100
14
I added the album to the group by
clause, as one might expect homonym titles across different albums.
If you want this for multiple years at once, then I would recommend window functions:
1CREATE TABLE `scrobbles` (
2 `id` INT(11) NOT NULL AUTO_INCREMENT,
3 `artist` VARCHAR(128) NULL DEFAULT '',
4 `album` VARCHAR(128) NULL DEFAULT '',
5 `title` VARCHAR(128) NULL DEFAULT '',
6 `datahora` DATETIME NULL DEFAULT current_timestamp(),
7 PRIMARY KEY (`id`)
8)ENGINE=InnoDB;
9select artist, album, title, count(*) cnt
10from scrobbles
11where datahora >= '2019-01-01' and datahora < '2020-01-01'
12group by artist, album, title
13order by count(*) desc limit 100
14select *
15from (
16 select artist, album, title, year(datahora) yr, count(*) cnt,
17 rank() over(partition by year(datahora) order by count(*) desc) rn
18 from scrobbles
19 group by artist, album, title
20) t
21where rn <= 100
22order by yr, cnt desc
23
Another benfit of this approach is that it allows bottom ties; it might return more than 100 rows per year if there happened to be ties in the last position.
QUESTION
How to code excel cells so that when you input data it automatically calculates what you enter + the previous cell
Asked 2020-Dec-03 at 14:49I hope this question isn't too obvious for this, I tried google but didn't know how to word this correctly so I thought i'd ask here. I used to use Excel a lot more but haven't in a while so I don't remember anything really. (Sorry if I don't use the right terms and if it's very wordy but I'll try my best to explain what I'm asking for)
Basically, I am making a spreadsheet on my spotify data (using lastfm to get the data)
The top row has every date of the year and the first column shows the Artist names. What I want to do is make it so that if for example; on January 1st I listened to "Artist A" 12 times, i'd put 12 into January 1st, but if I listened to "Artist A" 2 times on January 2nd, I wouldn't show 2 I'd show 14 as that'd be the total amount I'd listened to that artist so far, and so on for each artist and date. I don't want to manually calculate everything, obviously in the example it was easy to simply figure out 12 + 2 but when it gets to larger numbers it'd just be time consuming to type into every cell "=12+2" I want to be able to select every cell and make it so that in future if I typed a number into the cell, it would display the sum of that number + whatever is displayed in the previous cell in that row.
I hope I've explained what I'm asking well enough.
Example of the data (screenshot):
ANSWER
Answered 2020-Dec-03 at 13:59Have you tried =SUM(CELL1+CELL2
QUESTION
I need to map through json
Asked 2020-Dec-02 at 14:301import React, {useEffect} from 'react';
2import {connect} from 'react-redux';
3
4import {
5 fetchSongs
6} from '../store/actions';
7
8const MainPage = ({songsData, fetchSongs}) => {
9
10 useEffect(() => {
11 fetchSongs()
12 }, []);
13
14 return (
15 <div className='songs'>
16 <ul>
17 {
18 Object.keys(songsData.songs).map(song =>
19 <li>{song.toptracks.track.name}</li>
20 )
21 }
22 </ul>
23 </div>
24 );
25};
26
27const mapStateToProps = state => {
28 return {
29 songsData: state.songs
30 }
31}
32
33const mapDispatchToProps = dispatch => {
34 return {
35 fetchSongs: () => dispatch(fetchSongs())
36 }
37}
38
39
40export default connect(mapStateToProps, mapDispatchToProps)(MainPage);
41
this is my component. Here I have to get the data. It seems to me that I need to convert it into array but don't know how to do it. I've tried Object.values, Object.keys but it doesn't work. Uncaught TypeError: Cannot read property 'name' of undefined or 'map' is not a function
below is part of my json:
{"toptracks":{"track":[{"name":"Believe","playcount":"2750126","listeners":"536950","mbid":"32ca187e-ee25-4f18-b7d0-3b6713f24635","url":"https://www.last.fm/music/Cher/_/Believe","streamable":"0","artist":{"name":"Cher","mbid":"bfcc6d75-a6a5-4bc6-8282-47aec8531818","url":"https://www.last.fm/music/Cher"},"image":[{"#text":"https://lastfm.freetls.fastly.net/i/u/34s/2a96cbd8b46e442fc41c2b86b821562f.png","size":"small"},{"#text":"https://lastfm.freetls.fastly.net/i/u/64s/2a96cbd8b46e442fc41c2b86b821562f.png","size":"medium"},{"#text":"https://lastfm.freetls.fastly.net/i/u/174s/2a96cbd8b46e442fc41c2b86b821562f.png","size":"large"},{"#text":"https://lastfm.freetls.fastly.net/
enter code here
i/u/300x300/2a96cbd8b46e442fc41c2b86b821562f.png","size":"extralarge"}],"@attr":{"rank":"1"}}
import * as actionTypes from './../actions/actionTypes';
const initialState = { loading: false, songs: [], error: '' }
reducer below:
1import React, {useEffect} from 'react';
2import {connect} from 'react-redux';
3
4import {
5 fetchSongs
6} from '../store/actions';
7
8const MainPage = ({songsData, fetchSongs}) => {
9
10 useEffect(() => {
11 fetchSongs()
12 }, []);
13
14 return (
15 <div className='songs'>
16 <ul>
17 {
18 Object.keys(songsData.songs).map(song =>
19 <li>{song.toptracks.track.name}</li>
20 )
21 }
22 </ul>
23 </div>
24 );
25};
26
27const mapStateToProps = state => {
28 return {
29 songsData: state.songs
30 }
31}
32
33const mapDispatchToProps = dispatch => {
34 return {
35 fetchSongs: () => dispatch(fetchSongs())
36 }
37}
38
39
40export default connect(mapStateToProps, mapDispatchToProps)(MainPage);
41export const songsReducer = (state = initialState, action) => {
42 switch (action.type) {
43 case actionTypes.FETCH_SONG_REQUEST:
44 return {
45 ...state,
46 loading: true
47 }
48 case actionTypes.FETCH_SONG_SUCCESS:
49 return {
50 ...state,
51 songs: action.payload,
52 error: ''
53 }
54 case actionTypes.FETCH_SONG_FAILURE:
55 return {
56 loading: false,
57 songs: [],
58 error: action.payload
59 }
60 default:
61 return state;
62 }
63}
64
it's action:
1import React, {useEffect} from 'react';
2import {connect} from 'react-redux';
3
4import {
5 fetchSongs
6} from '../store/actions';
7
8const MainPage = ({songsData, fetchSongs}) => {
9
10 useEffect(() => {
11 fetchSongs()
12 }, []);
13
14 return (
15 <div className='songs'>
16 <ul>
17 {
18 Object.keys(songsData.songs).map(song =>
19 <li>{song.toptracks.track.name}</li>
20 )
21 }
22 </ul>
23 </div>
24 );
25};
26
27const mapStateToProps = state => {
28 return {
29 songsData: state.songs
30 }
31}
32
33const mapDispatchToProps = dispatch => {
34 return {
35 fetchSongs: () => dispatch(fetchSongs())
36 }
37}
38
39
40export default connect(mapStateToProps, mapDispatchToProps)(MainPage);
41export const songsReducer = (state = initialState, action) => {
42 switch (action.type) {
43 case actionTypes.FETCH_SONG_REQUEST:
44 return {
45 ...state,
46 loading: true
47 }
48 case actionTypes.FETCH_SONG_SUCCESS:
49 return {
50 ...state,
51 songs: action.payload,
52 error: ''
53 }
54 case actionTypes.FETCH_SONG_FAILURE:
55 return {
56 loading: false,
57 songs: [],
58 error: action.payload
59 }
60 default:
61 return state;
62 }
63}
64import axios from 'axios';
65
66import * as actionTypes from './actionTypes';
67
68export const fetchSongRequest = () => {
69 return {
70 type: actionTypes.FETCH_SONG_REQUEST
71 }
72}
73
74export const fetchSongSuccess = (songs) => {
75 return {
76 type: actionTypes.FETCH_SONG_SUCCESS,
77 payload: songs
78 }
79}
80
81export const fetchSongFailure = (error) => {
82 return {
83 type: actionTypes.FETCH_SONG_FAILURE,
84 payload: error
85 }
86}
87
88export const fetchSongs = () => {
89 return (dispatch) => {
90 dispatch(fetchSongRequest)
91 axios
92 .get('http://ws.audioscrobbler.com/2.0/?method=artist.gettoptracks&artist=cher&api_key=c17b1886d9465542a9cd32437c804db6&format=json')
93 .then(response => {
94 const songs = response.data;
95 dispatch(fetchSongSuccess(songs))
96 })
97 .catch(error => {
98 const errorMsg = error.message;
99 dispatch(fetchSongFailure(errorMsg))
100 })
101 }
102}
103
ANSWER
Answered 2020-Dec-02 at 14:30Object.keys(songsData.songs).map()
is uncessary.
From the JSON, We can see that the array we want to iterate over is songsData.songs.toptracks.track
.
Also, in the state, songs
is initialised as an empty array. But event FETCH_SONG_SUCCESS
changes songs
to be an object. It should ideally be initialised as songs: {}
in the initialState
And for initial render - where songs
is still empty, it does not have property toptracks
on it. So we have to make sure songsData.songs.toptracks
is truthy before we actually access and iterate over songsData.songs.toptracks.track
.
Here is the snippet that should do the job:
1import React, {useEffect} from 'react';
2import {connect} from 'react-redux';
3
4import {
5 fetchSongs
6} from '../store/actions';
7
8const MainPage = ({songsData, fetchSongs}) => {
9
10 useEffect(() => {
11 fetchSongs()
12 }, []);
13
14 return (
15 <div className='songs'>
16 <ul>
17 {
18 Object.keys(songsData.songs).map(song =>
19 <li>{song.toptracks.track.name}</li>
20 )
21 }
22 </ul>
23 </div>
24 );
25};
26
27const mapStateToProps = state => {
28 return {
29 songsData: state.songs
30 }
31}
32
33const mapDispatchToProps = dispatch => {
34 return {
35 fetchSongs: () => dispatch(fetchSongs())
36 }
37}
38
39
40export default connect(mapStateToProps, mapDispatchToProps)(MainPage);
41export const songsReducer = (state = initialState, action) => {
42 switch (action.type) {
43 case actionTypes.FETCH_SONG_REQUEST:
44 return {
45 ...state,
46 loading: true
47 }
48 case actionTypes.FETCH_SONG_SUCCESS:
49 return {
50 ...state,
51 songs: action.payload,
52 error: ''
53 }
54 case actionTypes.FETCH_SONG_FAILURE:
55 return {
56 loading: false,
57 songs: [],
58 error: action.payload
59 }
60 default:
61 return state;
62 }
63}
64import axios from 'axios';
65
66import * as actionTypes from './actionTypes';
67
68export const fetchSongRequest = () => {
69 return {
70 type: actionTypes.FETCH_SONG_REQUEST
71 }
72}
73
74export const fetchSongSuccess = (songs) => {
75 return {
76 type: actionTypes.FETCH_SONG_SUCCESS,
77 payload: songs
78 }
79}
80
81export const fetchSongFailure = (error) => {
82 return {
83 type: actionTypes.FETCH_SONG_FAILURE,
84 payload: error
85 }
86}
87
88export const fetchSongs = () => {
89 return (dispatch) => {
90 dispatch(fetchSongRequest)
91 axios
92 .get('http://ws.audioscrobbler.com/2.0/?method=artist.gettoptracks&artist=cher&api_key=c17b1886d9465542a9cd32437c804db6&format=json')
93 .then(response => {
94 const songs = response.data;
95 dispatch(fetchSongSuccess(songs))
96 })
97 .catch(error => {
98 const errorMsg = error.message;
99 dispatch(fetchSongFailure(errorMsg))
100 })
101 }
102}
103<ul>
104 {songsData.songs.toptracks &&
105 songsData.songs.toptracks.track.map((aTrack) => <li>{aTrack.name}</li>)}
106</ul>
107
108
QUESTION
Big text on the right side pushes to the image on the left side
Asked 2020-Oct-11 at 13:58I'm using TailwindCSS to create a simple view with an image and a text. On mobile (smaller than md
) the image should be centered. The text should be below the image. For the other screens the image should be on the left side and the text should be on the right side, right next to the image but with a small margin.
Whenever the text does not exceed one line the CSS looks fine.
1<link href="https://unpkg.com/tailwindcss@1.8.13/dist/tailwind.min.css" rel="stylesheet" />
2
3<div class="md:flex">
4 <div class="flex justify-center items-center">
5 <img src="https://lastfm.freetls.fastly.net/i/u/270x205/92a6e1da897a4be19962d251717fabd7.jpg" class="rounded-full w-32 h-32 md:w-48 md:h-48 xl:w-64 xl:h-64" />
6 </div>
7 <div class="md:ml-20">
8 <h3 class="text-xl leading-7 font-semibold">
9 Header 1
10 </h3>
11 <p class="leading-6">
12 Lorem ipsum dolor sit amet
13 </p>
14 </div>
15</div>
But when it does, it pushes to the left side so the image shrinks down and the CSS is broken.
1<link href="https://unpkg.com/tailwindcss@1.8.13/dist/tailwind.min.css" rel="stylesheet" />
2
3<div class="md:flex">
4 <div class="flex justify-center items-center">
5 <img src="https://lastfm.freetls.fastly.net/i/u/270x205/92a6e1da897a4be19962d251717fabd7.jpg" class="rounded-full w-32 h-32 md:w-48 md:h-48 xl:w-64 xl:h-64" />
6 </div>
7 <div class="md:ml-20">
8 <h3 class="text-xl leading-7 font-semibold">
9 Header 1
10 </h3>
11 <p class="leading-6">
12 Lorem ipsum dolor sit amet
13 </p>
14 </div>
15</div><link href="https://unpkg.com/tailwindcss@1.8.13/dist/tailwind.min.css" rel="stylesheet" />
16
17<div class="md:flex">
18 <div class="flex justify-center items-center">
19 <img src="https://lastfm.freetls.fastly.net/i/u/270x205/92a6e1da897a4be19962d251717fabd7.jpg" class="rounded-full w-32 h-32 md:w-48 md:h-48 xl:w-64 xl:h-64" />
20 </div>
21 <div class="md:ml-20">
22 <h3 class="text-xl leading-7 font-semibold">
23 Header 1
24 </h3>
25 <p class="mt-2 leading-6">
26 Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata
27 sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea
28 rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
29 At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
30 </p>
31 </div>
32</div>
I would expect the text just to add more lines of text instead of pushing to the left. Does someone know how to fix this?
ANSWER
Answered 2020-Oct-11 at 13:58Adding flex-shrink: 0
to your image's container should fix it.
Edit: As @Question3r pointed out in the comments, a better way would be to apply the class flex-shrink-0
to the image's container.
1<link href="https://unpkg.com/tailwindcss@1.8.13/dist/tailwind.min.css" rel="stylesheet" />
2
3<div class="md:flex">
4 <div class="flex justify-center items-center">
5 <img src="https://lastfm.freetls.fastly.net/i/u/270x205/92a6e1da897a4be19962d251717fabd7.jpg" class="rounded-full w-32 h-32 md:w-48 md:h-48 xl:w-64 xl:h-64" />
6 </div>
7 <div class="md:ml-20">
8 <h3 class="text-xl leading-7 font-semibold">
9 Header 1
10 </h3>
11 <p class="leading-6">
12 Lorem ipsum dolor sit amet
13 </p>
14 </div>
15</div><link href="https://unpkg.com/tailwindcss@1.8.13/dist/tailwind.min.css" rel="stylesheet" />
16
17<div class="md:flex">
18 <div class="flex justify-center items-center">
19 <img src="https://lastfm.freetls.fastly.net/i/u/270x205/92a6e1da897a4be19962d251717fabd7.jpg" class="rounded-full w-32 h-32 md:w-48 md:h-48 xl:w-64 xl:h-64" />
20 </div>
21 <div class="md:ml-20">
22 <h3 class="text-xl leading-7 font-semibold">
23 Header 1
24 </h3>
25 <p class="mt-2 leading-6">
26 Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata
27 sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea
28 rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
29 At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
30 </p>
31 </div>
32</div><link href="https://unpkg.com/tailwindcss@1.8.13/dist/tailwind.min.css" rel="stylesheet" />
33
34<div class="md:flex">
35 <div class="flex justify-center items-center" style="flex-shrink: 0">
36 <img src="https://lastfm.freetls.fastly.net/i/u/270x205/92a6e1da897a4be19962d251717fabd7.jpg" class="rounded-full w-32 h-32 md:w-48 md:h-48 xl:w-64 xl:h-64" />
37 </div>
38 <div class="md:ml-20">
39 <h3 class="text-xl leading-7 font-semibold">
40 Header 1
41 </h3>
42 <p class="mt-2 leading-6">
43 Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata
44 sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea
45 rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
46 At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
47 </p>
48 </div>
49</div>
QUESTION
Model associations problem: NoMethodError: undefined method `extensions' for #<Hash...>
Asked 2020-Jul-31 at 11:38I'm currently upgrading my rails 5.2 app to rails 6.0 while following the upgrading guide.
Everything seems to work perfectly fine until I've encountered an error when one of my user classes (label or artist) interacts with the links model.
When I try to sign up either as an artist or as a label, I receive the following error when I get to the point where I need to define links to the user's social media or website:
1Completed 500 Internal Server Error in 139ms (ActiveRecord: 7.3ms | Allocations: 14518)
2
3 NoMethodError - undefined method `extensions' for #<Hash:0x000000000bdd4ec8>
4 Did you mean? extend:
5 app/controllers/label/personal_informations_controller.rb:8:in `edit'
6
Here is my personal_informations_controller: (the error is at line 8 which I'll mark so it will be clear)
1Completed 500 Internal Server Error in 139ms (ActiveRecord: 7.3ms | Allocations: 14518)
2
3 NoMethodError - undefined method `extensions' for #<Hash:0x000000000bdd4ec8>
4 Did you mean? extend:
5 app/controllers/label/personal_informations_controller.rb:8:in `edit'
6class Label::PersonalInformationsController < LabelController
7 layout "signup"
8 skip_before_action :ensure_approved
9
10 def edit
11 prepare_country_options
12 @label = current_label
13 @label.links.build(links_attributes) #***ERROR OCCURS HERE***#
14 end
15
16 def update
17 @label = current_label
18 if @label.update_attributes(label_params)
19 redirect_to edit_label_genres_path
20 else
21 update_error
22 end
23 end
24
25 private
26
27 def update_error
28 prepare_country_options
29 @label.links.build(links_attributes)
30 render :edit
31 end
32
33 def label_params
34 params.require(:label).permit(:logo, :city, :country_code, :profile, links_attributes: [:id, :source, :url])
35 end
36
37 def prepare_country_options
38 @country_options ||= Countries.prioritized.map { |country| [country.name, country.code] }
39 end
40
41 def links_attributes
42 link_sources.map { |source| {source: source } }
43 end
44
45 def link_sources
46 Link.sources - @label.links.map(&:source)
47 end
48
49end
50
So far, I've tried 3 solutions:
- Checking if this bug has anything to do with the change in the default autoloader to Zeitwerk, after checking it for a while I've came to the conclusion that it doesn't have anything to do with it.
- Checking if this bug has anything to do with the fact I'm using the Discogs API in order to automatically extract links if possible for the newcomer user. But when I mentioned @label.links to specifically point to my Discogs file in my services directory, it messed up everything as it was no longer pointing to the 'Link' model as it should have.
- Adding
belongs_to :label
association in my link.rb model. Unfortunately, it didn't change anything.
I'm attaching my Link model below:
1Completed 500 Internal Server Error in 139ms (ActiveRecord: 7.3ms | Allocations: 14518)
2
3 NoMethodError - undefined method `extensions' for #<Hash:0x000000000bdd4ec8>
4 Did you mean? extend:
5 app/controllers/label/personal_informations_controller.rb:8:in `edit'
6class Label::PersonalInformationsController < LabelController
7 layout "signup"
8 skip_before_action :ensure_approved
9
10 def edit
11 prepare_country_options
12 @label = current_label
13 @label.links.build(links_attributes) #***ERROR OCCURS HERE***#
14 end
15
16 def update
17 @label = current_label
18 if @label.update_attributes(label_params)
19 redirect_to edit_label_genres_path
20 else
21 update_error
22 end
23 end
24
25 private
26
27 def update_error
28 prepare_country_options
29 @label.links.build(links_attributes)
30 render :edit
31 end
32
33 def label_params
34 params.require(:label).permit(:logo, :city, :country_code, :profile, links_attributes: [:id, :source, :url])
35 end
36
37 def prepare_country_options
38 @country_options ||= Countries.prioritized.map { |country| [country.name, country.code] }
39 end
40
41 def links_attributes
42 link_sources.map { |source| {source: source } }
43 end
44
45 def link_sources
46 Link.sources - @label.links.map(&:source)
47 end
48
49end
50class Link < ApplicationRecord
51
52
53 LINKS_ORDERED = ['website', 'facebook', 'twitter', 'youtube', 'soundcloud', 'lastfm']
54
55 def self.ordered_links
56 ret = "CASE"
57 LINKS_ORDERED.each_with_index do |p, i|
58 ret << " WHEN source = '#{p}' THEN #{i}"
59 end
60 ret << " END"
61 end
62
63 validates :url, presence: true
64 default_scope { {order: ordered_links} }
65
66 def self.website
67 where(source: "website" )
68 end
69
70 def self.sources
71 ["website", "facebook", "twitter", "youtube", "soundcloud", "lastfm"]
72 end
73
74 def self.icons
75 ["globe", "facebook", "twitter", "youtube", "soundcloud", "lastfm"]
76 end
77
78 def to_partial_path
79 "links/#{source}"
80 end
81
82 def account_name
83 is_social_account? ? url.split("/").last : domain
84 end
85
86 def source
87 read_attribute(:source) # guessed_source || ...
88 end
89
90 def icon
91 self.class.icons[self.class.sources.index(source)]
92 end
93
94 def url=(url)
95 url = "http://#{url}" unless url =~ /^https?\:\/\//
96 write_attribute(:url, url)
97 end
98
99 private
100
101 def is_social_account?
102 (self.class.sources - ["website"]).include? source
103 end
104
105 def guessed_source
106 self.class.sources.find { |source| url =~ /#{source}/ }
107 end
108
109 def domain
110 url.gsub(/https?\:\/\//, "").split("/").first
111 end
112
113end
114
And my Label model:
1Completed 500 Internal Server Error in 139ms (ActiveRecord: 7.3ms | Allocations: 14518)
2
3 NoMethodError - undefined method `extensions' for #<Hash:0x000000000bdd4ec8>
4 Did you mean? extend:
5 app/controllers/label/personal_informations_controller.rb:8:in `edit'
6class Label::PersonalInformationsController < LabelController
7 layout "signup"
8 skip_before_action :ensure_approved
9
10 def edit
11 prepare_country_options
12 @label = current_label
13 @label.links.build(links_attributes) #***ERROR OCCURS HERE***#
14 end
15
16 def update
17 @label = current_label
18 if @label.update_attributes(label_params)
19 redirect_to edit_label_genres_path
20 else
21 update_error
22 end
23 end
24
25 private
26
27 def update_error
28 prepare_country_options
29 @label.links.build(links_attributes)
30 render :edit
31 end
32
33 def label_params
34 params.require(:label).permit(:logo, :city, :country_code, :profile, links_attributes: [:id, :source, :url])
35 end
36
37 def prepare_country_options
38 @country_options ||= Countries.prioritized.map { |country| [country.name, country.code] }
39 end
40
41 def links_attributes
42 link_sources.map { |source| {source: source } }
43 end
44
45 def link_sources
46 Link.sources - @label.links.map(&:source)
47 end
48
49end
50class Link < ApplicationRecord
51
52
53 LINKS_ORDERED = ['website', 'facebook', 'twitter', 'youtube', 'soundcloud', 'lastfm']
54
55 def self.ordered_links
56 ret = "CASE"
57 LINKS_ORDERED.each_with_index do |p, i|
58 ret << " WHEN source = '#{p}' THEN #{i}"
59 end
60 ret << " END"
61 end
62
63 validates :url, presence: true
64 default_scope { {order: ordered_links} }
65
66 def self.website
67 where(source: "website" )
68 end
69
70 def self.sources
71 ["website", "facebook", "twitter", "youtube", "soundcloud", "lastfm"]
72 end
73
74 def self.icons
75 ["globe", "facebook", "twitter", "youtube", "soundcloud", "lastfm"]
76 end
77
78 def to_partial_path
79 "links/#{source}"
80 end
81
82 def account_name
83 is_social_account? ? url.split("/").last : domain
84 end
85
86 def source
87 read_attribute(:source) # guessed_source || ...
88 end
89
90 def icon
91 self.class.icons[self.class.sources.index(source)]
92 end
93
94 def url=(url)
95 url = "http://#{url}" unless url =~ /^https?\:\/\//
96 write_attribute(:url, url)
97 end
98
99 private
100
101 def is_social_account?
102 (self.class.sources - ["website"]).include? source
103 end
104
105 def guessed_source
106 self.class.sources.find { |source| url =~ /#{source}/ }
107 end
108
109 def domain
110 url.gsub(/https?\:\/\//, "").split("/").first
111 end
112
113end
114class Label < ApplicationRecord
115 devise :database_authenticatable, :registerable,
116 :recoverable, :rememberable, :trackable, :validatable, :omniauthable
117 include PgSearch::Model
118
119 has_attached_file :logo, :s3_protocol => :https,
120 styles: { medium: "350x360#", thumb: "40x40#" },
121 default_url: ":class/:attachment/missing_:style.jpg"
122 validates_attachment_content_type :logo, content_type: %r{\Aimage/.*\Z}
123 alias_method :avatar, :logo
124
125 has_and_belongs_to_many :genres
126 has_many :feedback_requests
127 has_many :payment_types, as: :payee
128 has_many :links, as: :linkable, dependent: :destroy
129 has_many :releases
130 has_many :label_artists
131 has_many :sent_messages, as: :from, class_name: "Message"
132 has_many :messages, through: :conversations
133 has_many :conversations
134 has_many :songs, through: :feedback_requests, source: :song
135 has_many :artist_contacts, through: :songs, source: :artist
136 has_many :contracts, through: :conversations
137
138 accepts_nested_attributes_for :payment_types
139 accepts_nested_attributes_for :links, reject_if: ->(attributes) { attributes[:url].blank? }
140
141 validates :name, :real_name, presence: true
142 validates :city, :country_code, :profile, presence: true, on: :update
143
144 delegate :name, to: :country, prefix: true, allow_nil: true
145
146 pg_search_scope :search,
147 against: :name,
148 associated_against: { genres: :name },
149 using: {
150 tsearch: { dictionary: :english }
151 }
152
153 pg_search_scope :by_relevance,
154 associated_against: { genres: :name },
155 using: {
156 tsearch: { dictionary: :english, any_word: true }
157 }
158
159 def self.approved
160 where("approved_at IS NOT NULL")
161 end
162
163 def approved?
164 approved_at.present?
165 end
166
167 def payment_type
168 payment_types.order("created_at").last
169 end
170
171 def display_name
172 name
173 end
174
175 def country
176 Country.new(code: country_code)
177 end
178
179 def location
180 [city, country_name].compact.join(", ")
181 end
182
183 def logo_url(style = :medium)
184 logo.url(style)
185 end
186
187 # The profit the label has earned (deducting Sendemo's cut)
188 def balance_net
189 ((raw_balance.to_i/100.0) * (1-Payment.sendemo_fee_fraction)).round(2) if raw_balance.present?
190 end
191
192 # A label's balance is the entire balance charged through the label including Sendemo's fee.
193 # This is for backwards compatibility and should be changed
194 def balance=(new_balance)
195 write_attribute(:balance, (new_balance.to_f*100).to_i) if new_balance.present?
196 end
197
198 def balance
199 (raw_balance.to_i/100.0).round(2) if raw_balance.present?
200 end
201
202 def raw_balance
203 read_attribute(:balance)
204 end
205
206 def unread_messages_count
207 messages.unread.count
208 end
209
210 def unread_messages?
211 unread_messages_count > 0
212 end
213end
214
It is important to mention that when I'm trying to write in the rails console to see if my current_label has any other property it should have as mentioned in my Label model, the answer is always either positive or nil. The only problem which raises an error is when checking for @label.links
For example:
1Completed 500 Internal Server Error in 139ms (ActiveRecord: 7.3ms | Allocations: 14518)
2
3 NoMethodError - undefined method `extensions' for #<Hash:0x000000000bdd4ec8>
4 Did you mean? extend:
5 app/controllers/label/personal_informations_controller.rb:8:in `edit'
6class Label::PersonalInformationsController < LabelController
7 layout "signup"
8 skip_before_action :ensure_approved
9
10 def edit
11 prepare_country_options
12 @label = current_label
13 @label.links.build(links_attributes) #***ERROR OCCURS HERE***#
14 end
15
16 def update
17 @label = current_label
18 if @label.update_attributes(label_params)
19 redirect_to edit_label_genres_path
20 else
21 update_error
22 end
23 end
24
25 private
26
27 def update_error
28 prepare_country_options
29 @label.links.build(links_attributes)
30 render :edit
31 end
32
33 def label_params
34 params.require(:label).permit(:logo, :city, :country_code, :profile, links_attributes: [:id, :source, :url])
35 end
36
37 def prepare_country_options
38 @country_options ||= Countries.prioritized.map { |country| [country.name, country.code] }
39 end
40
41 def links_attributes
42 link_sources.map { |source| {source: source } }
43 end
44
45 def link_sources
46 Link.sources - @label.links.map(&:source)
47 end
48
49end
50class Link < ApplicationRecord
51
52
53 LINKS_ORDERED = ['website', 'facebook', 'twitter', 'youtube', 'soundcloud', 'lastfm']
54
55 def self.ordered_links
56 ret = "CASE"
57 LINKS_ORDERED.each_with_index do |p, i|
58 ret << " WHEN source = '#{p}' THEN #{i}"
59 end
60 ret << " END"
61 end
62
63 validates :url, presence: true
64 default_scope { {order: ordered_links} }
65
66 def self.website
67 where(source: "website" )
68 end
69
70 def self.sources
71 ["website", "facebook", "twitter", "youtube", "soundcloud", "lastfm"]
72 end
73
74 def self.icons
75 ["globe", "facebook", "twitter", "youtube", "soundcloud", "lastfm"]
76 end
77
78 def to_partial_path
79 "links/#{source}"
80 end
81
82 def account_name
83 is_social_account? ? url.split("/").last : domain
84 end
85
86 def source
87 read_attribute(:source) # guessed_source || ...
88 end
89
90 def icon
91 self.class.icons[self.class.sources.index(source)]
92 end
93
94 def url=(url)
95 url = "http://#{url}" unless url =~ /^https?\:\/\//
96 write_attribute(:url, url)
97 end
98
99 private
100
101 def is_social_account?
102 (self.class.sources - ["website"]).include? source
103 end
104
105 def guessed_source
106 self.class.sources.find { |source| url =~ /#{source}/ }
107 end
108
109 def domain
110 url.gsub(/https?\:\/\//, "").split("/").first
111 end
112
113end
114class Label < ApplicationRecord
115 devise :database_authenticatable, :registerable,
116 :recoverable, :rememberable, :trackable, :validatable, :omniauthable
117 include PgSearch::Model
118
119 has_attached_file :logo, :s3_protocol => :https,
120 styles: { medium: "350x360#", thumb: "40x40#" },
121 default_url: ":class/:attachment/missing_:style.jpg"
122 validates_attachment_content_type :logo, content_type: %r{\Aimage/.*\Z}
123 alias_method :avatar, :logo
124
125 has_and_belongs_to_many :genres
126 has_many :feedback_requests
127 has_many :payment_types, as: :payee
128 has_many :links, as: :linkable, dependent: :destroy
129 has_many :releases
130 has_many :label_artists
131 has_many :sent_messages, as: :from, class_name: "Message"
132 has_many :messages, through: :conversations
133 has_many :conversations
134 has_many :songs, through: :feedback_requests, source: :song
135 has_many :artist_contacts, through: :songs, source: :artist
136 has_many :contracts, through: :conversations
137
138 accepts_nested_attributes_for :payment_types
139 accepts_nested_attributes_for :links, reject_if: ->(attributes) { attributes[:url].blank? }
140
141 validates :name, :real_name, presence: true
142 validates :city, :country_code, :profile, presence: true, on: :update
143
144 delegate :name, to: :country, prefix: true, allow_nil: true
145
146 pg_search_scope :search,
147 against: :name,
148 associated_against: { genres: :name },
149 using: {
150 tsearch: { dictionary: :english }
151 }
152
153 pg_search_scope :by_relevance,
154 associated_against: { genres: :name },
155 using: {
156 tsearch: { dictionary: :english, any_word: true }
157 }
158
159 def self.approved
160 where("approved_at IS NOT NULL")
161 end
162
163 def approved?
164 approved_at.present?
165 end
166
167 def payment_type
168 payment_types.order("created_at").last
169 end
170
171 def display_name
172 name
173 end
174
175 def country
176 Country.new(code: country_code)
177 end
178
179 def location
180 [city, country_name].compact.join(", ")
181 end
182
183 def logo_url(style = :medium)
184 logo.url(style)
185 end
186
187 # The profit the label has earned (deducting Sendemo's cut)
188 def balance_net
189 ((raw_balance.to_i/100.0) * (1-Payment.sendemo_fee_fraction)).round(2) if raw_balance.present?
190 end
191
192 # A label's balance is the entire balance charged through the label including Sendemo's fee.
193 # This is for backwards compatibility and should be changed
194 def balance=(new_balance)
195 write_attribute(:balance, (new_balance.to_f*100).to_i) if new_balance.present?
196 end
197
198 def balance
199 (raw_balance.to_i/100.0).round(2) if raw_balance.present?
200 end
201
202 def raw_balance
203 read_attribute(:balance)
204 end
205
206 def unread_messages_count
207 messages.unread.count
208 end
209
210 def unread_messages?
211 unread_messages_count > 0
212 end
213end
214>> @label.conversations
215=> #<ActiveRecord::Associations::CollectionProxy []>
216
217>> @label.name
218=> "Test Label"
219
220>> @label.links
221!! #<NoMethodError: undefined method `extensions' for #<Hash:0x000000001001f1e8>
222Did you mean? extend>
223
Thank you for assisting me!
ANSWER
Answered 2020-Jul-29 at 15:22I had a similar issue, and mine was this:
1Completed 500 Internal Server Error in 139ms (ActiveRecord: 7.3ms | Allocations: 14518)
2
3 NoMethodError - undefined method `extensions' for #<Hash:0x000000000bdd4ec8>
4 Did you mean? extend:
5 app/controllers/label/personal_informations_controller.rb:8:in `edit'
6class Label::PersonalInformationsController < LabelController
7 layout "signup"
8 skip_before_action :ensure_approved
9
10 def edit
11 prepare_country_options
12 @label = current_label
13 @label.links.build(links_attributes) #***ERROR OCCURS HERE***#
14 end
15
16 def update
17 @label = current_label
18 if @label.update_attributes(label_params)
19 redirect_to edit_label_genres_path
20 else
21 update_error
22 end
23 end
24
25 private
26
27 def update_error
28 prepare_country_options
29 @label.links.build(links_attributes)
30 render :edit
31 end
32
33 def label_params
34 params.require(:label).permit(:logo, :city, :country_code, :profile, links_attributes: [:id, :source, :url])
35 end
36
37 def prepare_country_options
38 @country_options ||= Countries.prioritized.map { |country| [country.name, country.code] }
39 end
40
41 def links_attributes
42 link_sources.map { |source| {source: source } }
43 end
44
45 def link_sources
46 Link.sources - @label.links.map(&:source)
47 end
48
49end
50class Link < ApplicationRecord
51
52
53 LINKS_ORDERED = ['website', 'facebook', 'twitter', 'youtube', 'soundcloud', 'lastfm']
54
55 def self.ordered_links
56 ret = "CASE"
57 LINKS_ORDERED.each_with_index do |p, i|
58 ret << " WHEN source = '#{p}' THEN #{i}"
59 end
60 ret << " END"
61 end
62
63 validates :url, presence: true
64 default_scope { {order: ordered_links} }
65
66 def self.website
67 where(source: "website" )
68 end
69
70 def self.sources
71 ["website", "facebook", "twitter", "youtube", "soundcloud", "lastfm"]
72 end
73
74 def self.icons
75 ["globe", "facebook", "twitter", "youtube", "soundcloud", "lastfm"]
76 end
77
78 def to_partial_path
79 "links/#{source}"
80 end
81
82 def account_name
83 is_social_account? ? url.split("/").last : domain
84 end
85
86 def source
87 read_attribute(:source) # guessed_source || ...
88 end
89
90 def icon
91 self.class.icons[self.class.sources.index(source)]
92 end
93
94 def url=(url)
95 url = "http://#{url}" unless url =~ /^https?\:\/\//
96 write_attribute(:url, url)
97 end
98
99 private
100
101 def is_social_account?
102 (self.class.sources - ["website"]).include? source
103 end
104
105 def guessed_source
106 self.class.sources.find { |source| url =~ /#{source}/ }
107 end
108
109 def domain
110 url.gsub(/https?\:\/\//, "").split("/").first
111 end
112
113end
114class Label < ApplicationRecord
115 devise :database_authenticatable, :registerable,
116 :recoverable, :rememberable, :trackable, :validatable, :omniauthable
117 include PgSearch::Model
118
119 has_attached_file :logo, :s3_protocol => :https,
120 styles: { medium: "350x360#", thumb: "40x40#" },
121 default_url: ":class/:attachment/missing_:style.jpg"
122 validates_attachment_content_type :logo, content_type: %r{\Aimage/.*\Z}
123 alias_method :avatar, :logo
124
125 has_and_belongs_to_many :genres
126 has_many :feedback_requests
127 has_many :payment_types, as: :payee
128 has_many :links, as: :linkable, dependent: :destroy
129 has_many :releases
130 has_many :label_artists
131 has_many :sent_messages, as: :from, class_name: "Message"
132 has_many :messages, through: :conversations
133 has_many :conversations
134 has_many :songs, through: :feedback_requests, source: :song
135 has_many :artist_contacts, through: :songs, source: :artist
136 has_many :contracts, through: :conversations
137
138 accepts_nested_attributes_for :payment_types
139 accepts_nested_attributes_for :links, reject_if: ->(attributes) { attributes[:url].blank? }
140
141 validates :name, :real_name, presence: true
142 validates :city, :country_code, :profile, presence: true, on: :update
143
144 delegate :name, to: :country, prefix: true, allow_nil: true
145
146 pg_search_scope :search,
147 against: :name,
148 associated_against: { genres: :name },
149 using: {
150 tsearch: { dictionary: :english }
151 }
152
153 pg_search_scope :by_relevance,
154 associated_against: { genres: :name },
155 using: {
156 tsearch: { dictionary: :english, any_word: true }
157 }
158
159 def self.approved
160 where("approved_at IS NOT NULL")
161 end
162
163 def approved?
164 approved_at.present?
165 end
166
167 def payment_type
168 payment_types.order("created_at").last
169 end
170
171 def display_name
172 name
173 end
174
175 def country
176 Country.new(code: country_code)
177 end
178
179 def location
180 [city, country_name].compact.join(", ")
181 end
182
183 def logo_url(style = :medium)
184 logo.url(style)
185 end
186
187 # The profit the label has earned (deducting Sendemo's cut)
188 def balance_net
189 ((raw_balance.to_i/100.0) * (1-Payment.sendemo_fee_fraction)).round(2) if raw_balance.present?
190 end
191
192 # A label's balance is the entire balance charged through the label including Sendemo's fee.
193 # This is for backwards compatibility and should be changed
194 def balance=(new_balance)
195 write_attribute(:balance, (new_balance.to_f*100).to_i) if new_balance.present?
196 end
197
198 def balance
199 (raw_balance.to_i/100.0).round(2) if raw_balance.present?
200 end
201
202 def raw_balance
203 read_attribute(:balance)
204 end
205
206 def unread_messages_count
207 messages.unread.count
208 end
209
210 def unread_messages?
211 unread_messages_count > 0
212 end
213end
214>> @label.conversations
215=> #<ActiveRecord::Associations::CollectionProxy []>
216
217>> @label.name
218=> "Test Label"
219
220>> @label.links
221!! #<NoMethodError: undefined method `extensions' for #<Hash:0x000000001001f1e8>
222Did you mean? extend>
223class Foo < ApplicationRecord
224 has_and_belongs_to_many :bars, -> { uniq }
225end
226
When I call .bars
on a Foo, I got the undefined_method: extensions
error.
The solution for me was to change -> { uniq }
to -> { distinct }
during Rails 6 migration.
Hope this helps someone.
QUESTION
How can I update a variable after render?
Asked 2020-Jul-02 at 17:22Hi this is my code in App.js
1var music = {
2 name: "Starboy",
3 artist: "The Weeknd",
4 albumArt: "",
5 length: "4:20",
6 audioURL:"",
7
8};
9
10export default class App extends Component
11{
12 render() {
13 return (
14 <Image style={styles.albumArt} source={{ uri:music.albumArt }} />
15 );
16 }
17};
18
I have another function in lastFM.js
1var music = {
2 name: "Starboy",
3 artist: "The Weeknd",
4 albumArt: "",
5 length: "4:20",
6 audioURL:"",
7
8};
9
10export default class App extends Component
11{
12 render() {
13 return (
14 <Image style={styles.albumArt} source={{ uri:music.albumArt }} />
15 );
16 }
17};
18export function getAlbumArt(albumName)
19{
20 fetch('http://ws.audioscrobbler.com/2.0/?method=album.search&album='+albumName+'&api_key=MY_API_KEY&format=json&limit=1')
21 .then((response) => response.json())
22 .then((result) => {
23 const image = result.results.albummatches.album[0].image[2]['#text'];
24 console.log(image);
25 return image;
26 })
27 .catch((error) => {
28 console.log("ERROR: "+error);
29 });
30}
31
How can I update music.albumArt in App.js and re-render Image inside App.js Render?
ANSWER
Answered 2020-Jul-02 at 17:22This might help. Re-render happens when you change the state of the component. So, here we are updating the state once we get data from the API.
1var music = {
2 name: "Starboy",
3 artist: "The Weeknd",
4 albumArt: "",
5 length: "4:20",
6 audioURL:"",
7
8};
9
10export default class App extends Component
11{
12 render() {
13 return (
14 <Image style={styles.albumArt} source={{ uri:music.albumArt }} />
15 );
16 }
17};
18export function getAlbumArt(albumName)
19{
20 fetch('http://ws.audioscrobbler.com/2.0/?method=album.search&album='+albumName+'&api_key=MY_API_KEY&format=json&limit=1')
21 .then((response) => response.json())
22 .then((result) => {
23 const image = result.results.albummatches.album[0].image[2]['#text'];
24 console.log(image);
25 return image;
26 })
27 .catch((error) => {
28 console.log("ERROR: "+error);
29 });
30}
31export default class App extends React.Component {
32 constructor() {
33 super();
34 this.state = {
35 name: "Starboy",
36 artist: "The Weeknd",
37 albumArt: "",
38 length: "4:20",
39 audioURL: ""
40 };
41 }
42 componentDidMount(){
43 fetch('http://ws.audioscrobbler.com/2.0/?method=album.search&album='+albumName+'&api_key=MY_API_KEY&format=json&limit=1')
44 .then((response) => response.json())
45 .then((result) => {
46 const image = result.results.albummatches.album[0].image[2]['#text'];
47 console.log(image);
48 this.setState({...this.state, albumArt: image });
49 })
50 .catch((error) => {
51 console.log("ERROR: "+error);
52 });
53 }
54 render() {
55 return <Image style={styles.albumArt} source={{ uri: this.state.albumArt }} />;
56 }
57}
58
Community Discussions contain sources that include Stack Exchange Network
Tutorials and Learning Resources in Lastfm
Tutorials and Learning Resources are not available at this moment for Lastfm