0

I am trying to search YouTube video by key like in the golang example. I modified that code a little to let it search by different keys several times.

When I search once it is ok.

func main() {
    result1, err1 := SearchYoutubeByKey("hello")

    if err1 != nil {
        panic(err1)
    }
    fmt.Println(result1)

    // result2, err2 := SearchYoutubeByKey("world")
    // if err2 != nil {
    //  panic(err2)
    // }
    // fmt.Println(result2)
}

But if I search twice ...

func main() {
    result1, err1 := SearchYoutubeByKey("hello")

    if err1 != nil {
        panic(err1)
    }
    fmt.Println(result1)

    result2, err2 := SearchYoutubeByKey("world")
    if err2 != nil {
        panic(err2)
    }
    fmt.Println(result2)
}

... then it panics with error message ...

flag redefined: query

... on line ...

query := flag.String("query", str, "Search term")

Full code:

package main

import (
    "code.google.com/p/google-api-go-client/googleapi/transport"
    "code.google.com/p/google-api-go-client/youtube/v3"
    "flag"
    "fmt"
    "net/http"
)

var (
    maxResults = flag.Int64("max-results", 25, "Max YouTube results")
    service    *youtube.Service
    response   *youtube.SearchListResponse
)

const developerKey = "youtube developer key"

type YoutubeSearchResult struct {
    Title, YoutubeId string
}

func SearchYoutubeByKey(str string) (result []*YoutubeSearchResult, err error) {
    query := flag.String("query", str, "Search term")
    flag.Parse()

    client := &http.Client{
        Transport: &transport.APIKey{Key: developerKey},
    }

    service, err = youtube.New(client)
    if err != nil {
        return
    }

    // Make the API call to YouTube.
    call := service.Search.List("id,snippet").
        Q(*query).
        MaxResults(*maxResults)
    response, err = call.Do()
    if err != nil {
        return
    }

    // Iterate through each item and add it to the correct list.
    for _, item := range response.Items {
        switch item.Id.Kind {
        case "youtube#video":
            result = append(result, &YoutubeSearchResult{Title: item.Snippet.Title, YoutubeId: item.Id.VideoId})
        }
    }
    return
}

func main() {


    result1, err1 := SearchYoutubeByKey("hello")

    if err1 != nil {
        panic(err1)
    }
    fmt.Println(result1)

    result2, err2 := SearchYoutubeByKey("world")
    if err2 != nil {
        panic(err2)
    }
    fmt.Println(result2)
}

So it is impossible to use this code on a website. Only the first user will be able to search first time, the others will fail.

I cannot change flag during runtime but how to search by 2 different keys in one program?

Update

working solution:

package main

import (
    "code.google.com/p/google-api-go-client/googleapi/transport"
    "code.google.com/p/google-api-go-client/youtube/v3"
    "flag"
    "fmt"
    "net/http"
)

var (
    maxResults = flag.Int64("max-results", 25, "Max YouTube results")
    service    *youtube.Service
    response   *youtube.SearchListResponse
    query      = flag.String("query", "str", "Search term")
)

const developerKey = "youtube api key"

type YoutubeSearchResult struct {
    Title, YoutubeId string
}

func SearchYoutubeByKey(str string) (result []*YoutubeSearchResult, err error) {
    flag.Parse()

    client := &http.Client{
        Transport: &transport.APIKey{Key: developerKey},
    }

    service, err = youtube.New(client)
    if err != nil {
        return
    }

    // Make the API call to YouTube.
    call := service.Search.List("id,snippet").
        Q(str).
        MaxResults(*maxResults)
    response, err = call.Do()
    if err != nil {
        return
    }

    // Iterate through each item and add it to the correct list.
    for _, item := range response.Items {
        switch item.Id.Kind {
        case "youtube#video":
            result = append(result, &YoutubeSearchResult{Title: item.Snippet.Title, YoutubeId: item.Id.VideoId})
        }
    }
    return
}

func main() {
    result1, err1 := SearchYoutubeByKey("hello")

    if err1 != nil {
        panic(err1)
    }
    fmt.Println(result1)

    result2, err2 := SearchYoutubeByKey("world")
    if err2 != nil {
        panic(err2)
    }
    fmt.Println(result2)
}
Grokify
  • 15,092
  • 6
  • 60
  • 81
Maxim Yefremov
  • 13,671
  • 27
  • 117
  • 166

1 Answers1

2

The panic message tells you exactly what's wrong. Your command line flags should be defined only once. If you try to redefine them during runtime, it panics.

Ainar-G
  • 34,563
  • 13
  • 93
  • 119
  • I guessed about that, how to solve it? how to search by 2 different keys during runtime – Maxim Yefremov Apr 14 '15 at 15:11
  • @efr Why do you use `flag` package there in the first place? From the YouTube example, it seems like you just need to pass `str` directly to `Q`. – Ainar-G Apr 14 '15 at 15:20
  • from the link above: `query = flag.String("query", "Google", "Search term")` - glag is used to set search key. How should I pass `str` directly to `Q`? – Maxim Yefremov Apr 15 '15 at 00:51
  • 3
    @efr Please read the [`flag` package documentation](http://golang.org/pkg/flag/) and what it's used for. In your case, you should just omit the `flag` part and call `Q(str)` instead of `Q(*query)`. – Ainar-G Apr 15 '15 at 11:46