1

My Component code:

products: Product[];
constructor(private productService: ProductService) { }

ngOnInit() {
    this.productService.getProducts()
        .subscribe(
        (products: Product[]) => {
            this.products = products;
        }
        );
}

My HTML Code:

                <tr *ngFor="let product of products">
                    <td>
                        <a [routerLink]="['/product-details', product.SKU]">{{ product.SKU }} </a>
                    </td>
                    <td>
                        <a [routerLink]="['/product-details', product.SKU]">{{ product.mrp }} </a>
                    </td>
                </tr>

My Service Code:

getProducts() {
    return this.http.get('http://localhost:3000/product')
        .map((response: Response) => {
            const products = response.json().obj;

            let transformedMessages: Product[] = [];
            for (let product of products) {
              transformedMessages.push(new Product(product.SKU, product.mrp, 111, 111));
            }
            this.products = transformedMessages;
            return transformedMessages;

            return products;

        })
        .catch((error: Response) => Observable.throw(error.json()));

My Backend route:

router.get('/', function (req, res, next) {
    Product.find().exec(function (err, products) {
        if (err) {
            return res.status(500).json({
                title: 'An error occurred',
                error: err
            });
        }
        res.status(200).json({
            message: 'Success',
            obj: products        //obj comes from here
        });
    });
});

Response:
{
"message": "Success",
"obj": [
{
"0": {
"SKU": "V2620151BR",
"Batch": "1",
"Folder Number": "85",
"MRP": "799",
"Size": "Free",
"Color": "Yellow",
},

My Backend Model Class:

var schema = new Schema({
    sku: { type: String, required: true, unique: true },
    mrp: { type: Number }
});

My Frontend Model:

export class Product {
    constructor(
        public SKU: string,
        public mrp: number,
        public selling_price: number,
        public current_inventory: number
    ) { }
}

enter image description here

My http://localhost:3000/product reutrns the json response correctly. But somehow in the HTML, when the page loads everything is empty.
I am only getting one value - empty empty 111 111

Most of the things are setup fine, I am not sure why the empty HTML when I get the response back from http://localhost:3000/product

good.learner
  • 121
  • 1
  • 2
  • 13

2 Answers2

1

I better suggest make change in your backend code and try to return json string structure like

Response:
{
"message": "Success",
"obj": [
{
"ProductId": "0",
"SKU": "V2620151BR",
"Batch": "1",
"Folder Number": "85",
"MRP": "799",
"Size": "Free",
"Color": "Yellow",
},
}

that will resolve your issue , without not much code change in front end i.e. in angular part


if you are not getting sturcture of reponse properly I sugest you make use of this potal : http://json2ts.com/ which helps to convert json string to typscript object.

for this structure given by you : { "0": { "SKU": "V2620151BR", "MRP": "799" }}

this is typescript object got created.

declare module namespace {
    export interface ProductDetail{
        SKU: string;
        MRP: string;
    }

    export interface ProductRoot{
        productDetail: ProductDetail;
    }
}

if you have above kind of structure than your code will be as below (i havent run code at my end but if there is any error please inform it should be like that only )

 getProducts() : Observable<Array<ProductDetail>>
     {
          return this.http.get('http://localhost:3000/product')
            .map((response: Response) => {
               debugger;//try to debug this part specially response returned 
                        //for server 
               let resproducts:Array<ProductRoot> = response.json().obj;

               let transformedMessages: ProductDetail[] = [];
              for (let product of resproducts) {
                 transformedMessages.push(new ProductDetail(product.productDetail.SKU, product.productDetail.mrp, 111, 111));
             }
              return transformedMessages;
        })
        .catch((error: Response) => Observable.throw(error.json()));

code in component

products: ProductDetail[];
constructor(private productService: ProductService) { }

ngOnInit() {
    this.productService.getProducts()
        .subscribe(
        (products: Product[]) => {
            this.products = products;
        }
        );
}

i suggest not to give same name to propeties , better keep name different - try below code

I am guessing here that your server code is returning json array of product

 getProducts() 
 {
      return this.http.get('http://localhost:3000/product')
        .map((response: Response) => {
           debugger;//try to debug this part specially response returned 
                    //for server 
           let resproducts:Array<Product> = response.json();

           let transformedMessages: Product[] = [];
          for (let product of resproducts) {
             transformedMessages.push(new Product(product.SKU, product.mrp, 111, 111));
         }
          return transformedMessages;
    })
    .catch((error: Response) => Observable.throw(error.json()));

component code

products: Product[];
constructor(private productService: ProductService) { }

ngOnInit() {
    this.productService.getProducts()
        .subscribe(
           (res) => {
               this.products = res;
             }
        );
}
Pranay Rana
  • 175,020
  • 35
  • 237
  • 263
  • @good.learner - check my update .. i given you changed code as per you strucutre – Pranay Rana Nov 29 '17 at 18:31
  • @good.learner - try to change strucutre of you json returning from server i.e. backend as i suggested in my answer – Pranay Rana Nov 29 '17 at 18:40
  • check my question, i have attached an image of the response. – good.learner Nov 29 '17 at 18:50
  • @good.learner -its difficult to create json out of it ... i see its dictionary kind of response "key-value" pair, i handled this kind of reponse in c# but not sure about typscript ...I suggest you just change your server response to simple structure.. – Pranay Rana Nov 29 '17 at 18:54
  • @good.learner - you need to do like this for key-value pair if you are going with your current structure :https://stackoverflow.com/questions/8785660/need-to-convert-json-key-value-pairs-to-standard-array this is in jquery you have to do same in typescript – Pranay Rana Nov 29 '17 at 19:04
  • @good.learner - to understand you json data you get row data in you component without any kind of cast and use json piple i.e. {{data|json}} in template on response received – Pranay Rana Nov 29 '17 at 19:06
  • issues resolved, the problem was my response structure – good.learner Nov 29 '17 at 19:33
  • @good.learner - that what i told you from beggining ....you have to change strucutre and things work for you......please upvote /accept if answer helped you ..else it ok – Pranay Rana Nov 29 '17 at 19:36
1

You are subscribing to the empty array in your case, because the return is executed before getting all the data. That's why it is better to use Promise

return this.http.get(url)
        .toPromise()
        .then((response) => {doSomething()});

If you want to keep your code, try to create an initial empty product and a real BehaviorSubject and emit the new value, then subscribe to this :

this.initialProduct = EMPTY_PRODUCT;

changeProduct: BehaviorSubject<Product or any> = new BehaviorSubject(this.initialProduct)

then just before the return this.changeProduct.emit(product); and subscribe to the answer instead of the get function : this.changeProduct.subscribe((product) => {doSomething()};

andrea06590
  • 1,259
  • 3
  • 10
  • 22