How to properly structure struct in struct - go

I started to learn Go and my (self assigned) mission is to print out a list of hard-coded albums and songs which are on this album.
I've created struct Album which is "object" of album. Inside this struct Album I want to create underlying struct Song. This "object" will hold songs of that album.
My problem/error that I'm getting is ./main.go:46:4: cannot use []Song literal (type []Song) as type Song in field value
This is my code.
// Song struct
type Song struct {
SongName string `json:"song_name"`
Position int `json:"position"`
Length string `json:"length"`
}
// Album struct
type Album struct {
Name string `json:"name"`
Artist string `json:"artist"`
YouTubeLink string `json:"youtube_link"`
AlbumImage string `json:"album_image"`
Description string `json:"description"`
ReleaseDate string `json:"release_date"`
RecordDate string `json:"record_date"`
Length string `json:"length"`
Studio string `json:"studio"`
Songs Song `json:"songs"`
}
func listOfAlbums() []Album {
a := []Album{
{
Name: "The Dark Side of the Moon",
Artist: "Pink Floyd",
YouTubeLink: "https://www.youtube.com/watch?v=HW-lXjOyUWo&list=PLEQdwrAGbxnc9lyYltGRUMt3OgfX0tFbd&index=1",
AlbumImage: "https://upload.wikimedia.org/wikipedia/sl/b/bb/Dsotm.jpg",
Description: "The Dark Side of the Moon is the eighth studio album by English rock band Pink Floyd, released on 1 March 1973 by Harvest Records. Primarily developed during live performances, the band premiered an early version of the record several months before recording began.",
ReleaseDate: "1973.03.01",
RecordDate: "1972.06.01 – 1973.01.01",
Length: "42:32",
Studio: "Abbey Road Studios, London",
//
// Problematic part of code
//
Songs: []Song{
{
SongName: "Speak to Me / Breathe",
Position: 1,
Length: "1:13",
},
{
SongName: "Breathe",
Position: 2,
Length: "2:43",
},
{
SongName: "On the run",
Position: 3,
Length: "3:36",
},
{
SongName: "Time",
Position: 4,
Length: "6:53",
},
{
SongName: "The Great Gig in the Sky",
Position: 5,
Length: "4:36",
},
{
SongName: "Money",
Position: 6,
Length: "6:23",
},
{
SongName: "Us and Them",
Position: 7,
Length: "7:49",
},
{
SongName: "Any Colour You Like",
Position: 8,
Length: "3:26",
},
{
SongName: "Brain Damage",
Position: 9,
Length: "3:49",
},
{
SongName: "Eclipse",
Position: 10,
Length: "2:03",
},
},
},
}
return a
}
Here is a working Go PlayGround code
The questions are following:
Is my logic going in to the right direction? Do I even need to create another struct (Song) or this could be solved in some better manner?
How should I restructure my code so it will be working?

In your Album struct, a single Song is expected for the Songs field. However, []Song is a slice (list type) of songs. When you update your struct declaration with []Song instead of Song, your definition is good.
type Album struct {
Name string `json:"name"`
Artist string `json:"artist"`
YouTubeLink string `json:"youtube_link"`
AlbumImage string `json:"album_image"`
Description string `json:"description"`
ReleaseDate string `json:"release_date"`
RecordDate string `json:"record_date"`
Length string `json:"length"`
Studio string `json:"studio"`
Songs []Song `json:"songs"`
}
Now you can use a []Song{...} for this field, which is also expected in your data definition.
Your code is totally fine and it is normal to use multiple structs for bigger objects that contain other objects.

Related

dynamoDb put item not populating all params

I have 2 lambdas that do the exact same thing, however, they are both written using different langages.
1st lambda - runs on a node.js environment, when I create my arguments to putItem, as follows:
const args = {
id: "my id",
__typename: "a type name",
_version: 1,
_lastChangedAt: now.toISOString(),
createdAt: now.toISOString(),
updatedAt: fields.LastModifiedDate
}
var recParams = {
TableName: dynamoTable,
Key: {
"id": Id
},
Item: args,
ReturnValues: "ALL_OLD"
};
and then I use the docClient to insert the row. Everything works fine, all the properties are populated in my dynamo row.
I have the exact same written in Golang:
item := RecentItem{
Id: "some Id",
_version: 1,
__typename: "a type name",
_lastChangedAt: currentTime.UTC().Format("2006-01-02T15:04:05-0700"),
createdAt: currentTime.UTC().Format("2006-01-02T15:04:05-0700"),
updatedAt: currentTime.UTC().Format("2006-01-02T15:04:05-0700"),
}
av, err := dynamodbattribute.MarshalMap(item)
input := &dynamodb.PutItemInput{
Item: av,
TableName: aws.String(tableName),
}
Everything ALMOST works, the item is inserted, but I am missing all the properties except for the id.
Structure declaration :
type RecentItem struct {
Id string `json:"id"`
_version int `json:"_version"`
_lastChangedAt string `json:"_lastChangedAt"`
createdAt string `json:"createdAt"`
updatedAt string `json:"updatedAt"`
}
Not sure why in Go my dynamoDb row is missing properties. Am I missing something?
Properties other than Id must be exported, i.e, started with an Upper case:
type RecentItem struct {
ID string `dynamodbav:"id"`
Version int `dynamodbav:"_version"`
LastChangedAt string `dynamodbav:"_lastChangedAt"`
CreatedAt string `dynamodbav:"createdAt"`
UpdatedAt string `dynamodbav:"updatedAt"`
}

Populate a struct with an array of sub-structs to turn into json

I’m trying to post some JSON. Using the JSON-to-Go tool I have this struct defined:
type IssueSetState struct {
ID string `json:"id"`
CustomFields []struct {
Value struct {
Name string `json:"name"`
} `json:"value"`
Name string `json:"name"`
Type string `json:"$type"`
} `json:"customFields"`
}
I’m trying to populate it with some data that I can then pass into the http library:
jsonValues := &IssueSetState{
ID: resultEntityId.ID,
CustomFields: []{
Value: {
Name: "Fixed",
},
Name: "State",
Type: "StateIssueCustomField",
},
}
jsonEncoded := new(bytes.Buffer)
json.NewEncoder(jsonEncoded).Encode(jsonValues)
I keep getting errors like:
./main.go:245:19: syntax error: unexpected {, expecting type
./main.go:246:9: syntax error: unexpected :, expecting comma or }
./main.go:249:8: syntax error: unexpected : at end of statement
./main.go:251:4: syntax error: unexpected comma after top level declaration
I’m sure the mistake I’m making is a simple one, but I’m new to Go.
One possible way is to define named structs for every anonymous struct you have.
type IssueSetState struct {
ID string `json:"id"`
CustomFields []CustomField `json:"customFields"`
}
type CustomField struct {
Value Value `json:"value"`
Name string `json:"name"`
Type string `json:"type"`
}
type Value struct {
Name string `json:"name"`
}
Now you can create it like this:
IssueSetState{
ID: resultEntityId.ID,
CustomFields: []CustomField{
{
Value: Value{
Name: "Fixed",
},
Name: "State",
Type: "StateIssueCustomField",
},
{
Value: Value{
Name: "Fixed",
},
Name: "State",
Type: "StateIssueCustomField",
},
},
}
So you're initializing the jsonValue badly.
You can fix it in 2 ways:
https://play.golang.org/p/LFO4tOLyG60
making structures flat
https://play.golang.org/p/TyFfaMf7XeF
by repeating the structure definition when declaring value
The first one should be easier and clearer.

What is the correct way to retrieve length of an array added a field in nested struct in golang

I have a nested struct and I need to find the length of an array which is one of the fields in the struct.
Here are the structs :
type TextEntry struct{
name string
Doc []DocEntry
}
type DocEntry struct {
rank: int
last: string
forward: string
}
Here's the struct initializer
a := TextEntry{
name: "a1",
Doc: []DocEntry{
{
rank: 1,
last: "a2",
forward: "always",
},
{
rank: 2,
last: "b2",
forward: "seldom",
},
},
}
My question is to use the correct way to find the length of []DocEntry which will be the value of Doc in TypeEntry struct
use this code:
len(a.Doc)
BTW you have syntax error in your "DocEntry" struct definition.
For full code please look at playground.

How to recall this struct?

how to recall this stryc?
struct User {
var name: String
var street: String
var city: String
var postalCode: String
func printAddress() -> String {
return """
\(name)
\(street)
\(city)
\(postalCode)
"""
}
}
I expect to have an address in different lines like the method, for example
Well Smith
streetnumber this one
lalaland
19890
but result comes back in struct form
Not sure what you mean with "recall struct" but if you want to print it in the expected format simply use printAddress()
let user = User(name: "name", street: "street", city: "city", postalCode: "postalCode")
print(user.printAddress())
Output:
name
street
city
postalCode

How to insert a record into an existing has many table with gorm

I have two tables
type Podcast struct {
Id int
Title string
RssUrl string `sql:"unique_index"`
Episodes []Episode
}
type Episode struct {
Id int
PodcastID int
Title string
Url string `sql:"unique_index"`
Downloaded bool
}
I know how to insert episodes into a new podcast like so.
podcast := Podcast{
Title: "My Podcast",
RssUrl: "http://example.com/feed/",
Url: "http://www.example.com",
Episodes: []Episode{{
Title: "Episode One Point Oh!",
Url: "http://www.example.com/one-point-oh",
Downloaded: false,
}},
}
db.Create(&podcast)
How do I go about adding episodes to a podcast that already exists later on?
I was able to figure it out.
var id int
row := db.Table("podcasts").Where("id = ?", 1).Select("id").Row()
row.Scan(&id)
episode := Episode{
Title: "Episode Two!",
Url: "http://www.example.com/episode-two",
Downloaded: true,
PodcastID: id,
}
db.Create(&episode)

Resources