Q:

How to use foreach loop in this case

I tried using foreach loop instead of while and it throws an error. I don't understand the problem why it isn't working in this case. Please someone help me in using foreach instead of while in the code below:
Foreach: tried but throwing errors

 $r=$mysqli->query("SELECT * from category");
                $row=$r->fetch_assoc();
                foreach($row as $cat)
                {?>
                    <tr class = "gradeX">
                      <td><?php echo $cat['cid'] ?></td>
                      <td><?php echo $cat['name'] ?></td>
                      <td><div class = "center"><a href = "#" class = "btn btn-primary btn-mini">Edit</a> <a href = "#" class = "btn btn-danger btn-mini">Delete</a></div></td>
                      </tr>
                  <?php }?>

While: Works perfectly

<?php
                $r=$mysqli->query("SELECT * from category");
                
                while($row=$r->fetch_assoc())
                {?>
                    <tr class = "gradeX">
                      <td><?php echo $row['cid'] ?></td>
                      <td><?php echo $row['name'] ?></td>
                      <td><div class = "center"><a href = "#" class = "btn btn-primary btn-mini">Edit</a> <a href = "#" class = "btn btn-danger btn-mini">Delete</a></div></td>
                      </tr>
                  <?php }?> 

A:

Lets look at your code:
$row=$r->fetch_assoc();
foreach($row as $cat)

Here you fetch a single row and then loop over it, so your $cat is the value of the fields in that row.  Not the next row.
So it's no surprise when you do this
  <td><?php echo $cat['cid'] ?></td>

And $cat = 'foo' (will have to imagine foo is the value of the cid column in the row, $row['cid'] = 'foo') that you get the error you are seeing.

Error: Illegal string offset 'cid' 

We can easily test this:
//if we agree this is a simplified way of doing what you are doing
<?php
    /*
       $row = $r->fetch_assoc();  //['cid' => 'foo']
       $cat = $row['cid']; //from foreach loop on $row
    */

     $cat = 'foo'
?>

<td><?php echo $cat['cid'] ?></td>

Output
<td><br />
<b>Warning</b>:  Illegal string offset 'cid' in <b>[...][...]</b> on line <b>6</b><br />
f</td>

Sandbox
When you do 
    while($row=$r->fetch_assoc())

The value of $row changes on each iteration, to the next row.  Using while to loop over the DB results is the expected way to do it.  Unless you fetch all the results and then loop over them, but in some cases that's less efficient. 
Hope that helps it make more sense.

