3

I am learning go and i need to understand something. I am getting few errors. I have created a Product struct and attached a func with it. I also got a product lists as a slice. Actually I am following one example. I was just trying add different endpoints to it.

I have added question in comment in code. Please explain. I need to return the json single object as a response to user. Please guide me.


package data 

type Product struct {
    ID          int     `json:"id"`
    Name        string  `json:"name"`
    Description string  `json:"description"`
    Price       float32 `json:"price"`
    SKU         string  `json:"sku"`
    CreatedOn   string  `json:"-"`
    UpdatedOn   string  `json:"-"`
    DeletedOn   string  `json:"-"`
}

type Products []*Product


func (p *Products) ToJSON(w io.Writer) error {
    e := json.NewEncoder(w)
    return e.Encode(p)
}

func (p *Product) FromJSON(r io.Reader) error {
    d := json.NewDecoder(r)
    return d.Decode(p)
}

var ErrProductNotFound = fmt.Errorf("Product not found")


func GetProduct(id int) (*Product, error) {       // this is returning *Product & err. When I use this in GetProduct in handler func it is giving error
    for _, p := range productList {
        if p.ID == id {
            fmt.Println(p)
            return p, nil
        }
    }
    return nil, ErrProductNotFound
}

var productList = []*Product{    **// Why in example the teacher doing it like this.** []*Product{&Product{}, &Product{}} **what it the reason? Please explain.
    &Product{                             // this gives warning : redundant type from array, slice, or map composite literal. need to understand why**

        ID:          1,
        Name:        "Latte",
        Description: "chai",
        Price:       2.45,
        SKU:         "abc123",
        CreatedOn:   time.Now().UTC().String(),
        UpdatedOn:   time.Now().UTC().String(),
    },
    &Product{
        ID:          2,
        Name:        "Tea",
        Description: "chai",
        Price:       1.45,
        SKU:         "abc1234",
        CreatedOn:   time.Now().UTC().String(),
        UpdatedOn:   time.Now().UTC().String(),
    },
}
package handlers

func (p *Product) GetProduct(rw http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    id, _ := strconv.Atoi(vars["id"])
    p, errr := data.GetProduct(id)  **// cannot use data.GetProduct(id) (value of type *data.Product) as *Product value in assignment**
    errr = p.ToJSON(rw) // **p.ToJSON undefined (type *Product has no field or method ToJSON)**
    if errr != nil {
        http.Error(rw, "could not locate the product", http.StatusBadGateway)
    }
}
4
  • The Product with the method GetProduct and the Product at the top of you code snippet, are they one and the same? Or are they declared in separate packages? Commented May 2, 2020 at 9:07
  • separate package Commented May 2, 2020 at 9:15
  • In that case the problem is that inside the GetProduct handler the variable p already has a type (handlers.Product) that is different from the one returned by the data.GetProduct function (data.Product). So what you can do is to use a different name for the variable that will store the result of data.GetProduct. Commented May 2, 2020 at 9:19
  • o yes, i got it, could you please explain other points Commented May 2, 2020 at 9:20

1 Answer 1

9

cannot use data.GetProduct(id) (value of type *data.Product) as *Product value in assignment

p.ToJSON undefined (type *Product has no field or method ToJSON)

The problem here is that inside the GetProduct handler the variable p already has a type (*handlers.Product) that is different from the one returned by the data.GetProduct function (*data.Product). So what you can do is to use a different name for the variable that will store the result of data.GetProduct.


Why in example the teacher doing it like this. []*Product{&Product{}, &Product{}} what it the reason? Please explain.

In general because that's one of the available methods for how to initialize a slice of structs, as per the language spec. Why the teacher used this method specifically? Unless the teacher confided the reason to someone, then no one would know, I certainly don't.


this gives warning : redundant type from array, slice, or map composite literal. need to understand why

Because it's true, it is redundant, as per the language spec, in a composite literal expression you can elide the types of the elements and keys.

For example a non-redundant version of the following composite literal:

[]*Product{&Product{}, &Product{}}

would look like this:

[]*Product{{}, {}}

and the result of these two expressions would be the same.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.