Django Rest Framework with React order not working

Viewed 161

I have a list in my application which is created from two related tables(products and stocks). I want to order items by date which is in the Stocks table. My API returns well ordered list but in my app the list is not ordered. When I try to order by any of Products fields it works fine - also in react.

My view:

class StocksView(viewsets.ModelViewSet):
    serializer_class = StocksSerializer
    ordering_fields = ['date']
    filter_backends = (filters.OrderingFilter,)
    def get_queryset(self):
        queryset = Stocks.objects.all().order_by('date')
        return queryset
    def perform_create(self, serializer):
        serializer.save(user=self.request.user)

Method from React:

  const fetchStocks = async () => {
    try {
      const response = await axiosInstance.get('/stocks/?ordering=date')
      if (response) {
        setStocksInfo(response.data)
        console.log(response.data)
      }
    } catch (error) {
      throw error;
    }
  }

And returned list from two merged tables:

{productsInfo.map(products => {
                  const product = stocksInfo.filter(e => e.product_id === products.product_id);
                  return (
                    product.map((stock, i) => (
                      <tr key={i} className="table-data">
                        <td className="col-3"> {products.name}</td>
                        <td className="col-3">{stock.date}</td>
                        <td className="col-1">{stock.count}</td>
                      </tr>
                    ))
                  )
                })}
1 Answers

Since you want to order based on the Stocks table, you should do the map from that array first.

You can make an implementation like this one, where you filter the stocks so it only has the ones matching from the productsInfo, and then mapping it.

{stocksInfo
    .filter(e => productsInfo.some(p => p.product_id === e.product_id))
    .map((stock, i) => {
        const products = productsInfo.find(e => e.product_id === stock.product_id);
        return (
            <tr key={i} className="table-data">
                <td className="col-3"> {products.name}</td>
                <td className="col-3">{stock.date}</td>
                <td className="col-1">{stock.count}</td>
            </tr>
        );
    })}

But, since that is inefficient, I would recommend combining both arrays and then mapping them. You can combine them with this code:

const combination = stocksInfo
    .map(item =>
        Object.assign(
            item,
            productsInfo.find(({product_id}) => product_id === item.product_id)
        )
    )
    .filter(item => item.name);

I also added a working example here:

const stocksInfo = [
    {date: "date1", count: 1, product_id: 123},
    {date: "date2", count: 2, product_id: 321},
    {date: "date3", count: 3, product_id: 331},
    {date: "date4", count: 4, product_id: 341},
];
const productsInfo = [
    {name: "test4", product_id: 341},
    {name: "test2", product_id: 321},
];

const combination = stocksInfo
        .map(item =>
            Object.assign(
                item,
                productsInfo.find(({product_id}) => product_id === item.product_id)
            )
        )
        .filter(item => item.name);


const Example = ({title}) => {

 return (
        <div>
            previous way
            <table>
                {productsInfo.map(products => {
                    const product = stocksInfo.filter(e => e.product_id === products.product_id);
                    return product.map((stock, i) => (
                        <tr key={i} className="table-data">
                            <td className="col-3"> {products.name}</td>
                            <td className="col-3">{stock.date}</td>
                            <td className="col-1">{stock.count}</td>
                        </tr>
                    ));
                })}
            </table>
            new way
            <table>
                {combination.map((stock, i) => {
                    return (
                        <tr key={i} className="table-data">
                            <td className="col-3"> {stock.name}</td>
                            <td className="col-3">{stock.date}</td>
                            <td className="col-1">{stock.count}</td>
                        </tr>
                    );
                })}
            </table>
        </div>
    );
};

// Render it
ReactDOM.render(
  <Example title="Example using Hooks:" />,
  document.getElementById("react")
);
table, td {
  border: 1px solid black;
  padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>

Related